﻿#coding=utf-8

import wx
import wx.lib.mixins.listctrl

import sys
from MyPrinter import TagPrinter
from product import *
from ctrlAider import *
import wx.lib.mixins.listctrl as listmix

from wx.lib.embeddedimage import PyEmbeddedImage
from myLogger import *
import kit

import datetime

from permitManager import PermitManager
from constant import const
import os
from ConfTool27 import conf


SmallUpArrow = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAADxJ"
    "REFUOI1jZGRiZqAEMFGke2gY8P/f3/9kGwDTjM8QnAaga8JlCG3CAJdt2MQxDCAUaOjyjKMp"
    "cRAYAABS2CPsss3BWQAAAABJRU5ErkJggg==")

#----------------------------------------------------------------------
SmallDnArrow = PyEmbeddedImage(
    "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAEhJ"
    "REFUOI1jZGRiZqAEMFGke9QABgYGBgYWdIH///7+J6SJkYmZEacLkCUJacZqAD5DsInTLhDR"
    "bcPlKrwugGnCFy6Mo3mBAQChDgRlP4RC7wAAAABJRU5ErkJggg==")

Width_BillId = 150
Width_Date = 90
Width_Unit = 50
    
class MyListCtrl(wx.ListCtrl, listmix.ColumnSorterMixin):
    '''在container中初始化列表，缺陷是只能处理对应单个数据表的数据，
        不能处理涉及多个数据表的情况
    '''
    
    def __init__(self, parent, clsDataModel, cols, style=wx.LC_REPORT|wx.LC_SINGLE_SEL):
        wx.ListCtrl.__init__(self, parent=parent, id=-1, style=style)
        self.dataModel = clsDataModel
        
        self.initCols(cols)
        self.itemDataMap = {}
        #self.data = [([]*len(cols)) for i in range(len(clsDataModel.m_dataList))] #copy data for sort
        #self.data = [([0]*len(cols)) for i in range(1000)]
        self.refreshData()
        
        listmix.ColumnSorterMixin.__init__(self, len(self.cols))
    
    def initCols(self, cols):
        self.cols = cols
        for i in range(len(cols)):
            self.InsertColumn(i, self.dataModel.getCNName(cols[i][0]))
            if cols[i][1] != -1:
                self.SetColumnWidth(i, cols[i][1])
                    
    def GetListCtrl(self):
        return self
    
    def refreshData(self):
        self.DeleteAllItems() 
        for obj in self.dataModel.m_dataList:
            index = self.InsertStringItem(sys.maxint, '')
            for i in range(len(self.cols)):

                val = obj.getFieldVal(self.cols[i][0])            
                if (val == None):
                    val = ''
                if (type(val) != str and type(val) != unicode):
                    val = str(val)
                
                self.SetStringItem(index, i, val)                
            self.SetItemData(index, index)
            self.itemDataMap[index]=obj
    
##    def Show(self, show=True):
##        print 'before Show()'
##        self.parent.Show(show)  


##class DataSource:
##    def GetColumnHeaders(self):
##        col = 0
##        text = 'fake col'
##        width = -1 #auto
##        return ((col,text,width))
##    
##    def GetDataMap(self):
##            '''获取DataMap，数据顺序要与GetItem(index)一致
##                return - {1:obj, 2:obj, ...}
##            '''
##            pass
##    def Notify(self):
##        '''数据源变动时，通知相关数据应用点'''
##        pass
##     
##    def listen(self, obj):
##        pass
        
class MyListCtrl2(wx.ListCtrl, listmix.ColumnSorterMixin):
    '''能排序的虚列表'''
    def __init__(self, parent, cols,
                    style=wx.LC_REPORT|wx.LC_SINGLE_SEL):
        wx.ListCtrl.__init__(self, parent, style=style)
        
##        self.dataSource = dataSource
##        cols = dataSource.GetColumnHeaders()
        for i in range(len(cols)):
            self.InsertColumn(i, self.dataModel.getCNName(cols[i][0]))
            if cols[i][1] != -1:
                self.SetColumnWidth(i, cols[i][1])
        
        #数据全部缓存到itemDataMap中，要注意数据源改变时，要对此同步
        #是不是不需要同步？因为字典的传值类似引用传递，itemDataMap直接指向了
        # dataSource中的datamap       
##        self.itemDataMap = dataSource.GetDataMap()
##        dataSource.listen(self)
        
        listmix.ColumnSorterMixin.__init__(self, len(self.cols))
    
##    def SyncData(self):
##        self.itemDataMap = dataSource.GetDataMap()
    
    def GetListCtrl(self):
        return self
    
    def appendRows(self, data):
        '''添加一行数据
            data - [,,,]
        '''
        index = self.InsertStringItem(sys.maxint, '')
        for val in enumerate((data)):      
            if (val is None):
                val = ''
            if (type(val) is str and type(val) is unicode):
                val = str(val)
            
            self.SetStringItem(index, i, val)
        
        self.SetItemData(index, index)
        self.itemDataMap[index]=data    
    
##    def OnGetItemText(self, item, col):
##        '''获取数据意味着要排序数据'''
##        #data = self.dataSource.GetItem(item)
##        data = 
##        return data[col]
##    
##    def refreshData(self):
##        self.DeleteAllItems() 
##        for obj in self.dataModel.m_dataList:
##            index = self.InsertStringItem(sys.maxint, '')
##            for i in range(len(self.cols)):
##
##                val = obj.getFieldVal(self.cols[i][0])            
##                if (val == None):
##                    val = ''
##                if (type(val) != str and type(val) != unicode):
##                    val = str(val)
##                
##                self.SetStringItem(index, i, val)                
##            self.SetItemData(index, index)
##            self.itemDataMap[index]=obj

class MyOrderListCtrl2(wx.ListCtrl, listmix.ColumnSorterMixin):
    '''显示订单列表'''
    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, style=wx.LC_REPORT|wx.LC_SINGLE_SEL)
        
        cols = [(u'订单号', -1), (u'客户名称', -1), (u'总金额',  -1), (u'已付金额',  -1), 
                (u'未付金额',  -1), (u'优惠金额', -1), (u'订单日期',  -1), 
                (u'配送方式',  -1), (u'备注',  -1), (u'经手人',  -1),
                (u'操作员', -1)]
        for i in range(len(cols)):
            self.InsertColumn(i, cols[i][0])
            if cols[i][1] != -1:
                self.SetColumnWidth(i, cols[i][1])
        
        self.COL_ID = 0
        
        listmix.ColumnSorterMixin.__init__(self, len(cols))
        
    def refreshData(self, filter={}):
        '''根据filter显示数据
            filter - {'custId':,'custName':,'dateStart':, 'dateEnd':}
        '''
        self.DeleteAllItems() 
        self.itemDataMap = {}
        filterSql = ''
            
        if (filter.has_key('dateStart')):
            filterSql += "billDate between '%s' and '%s'" \
                            %(filter['dateStart'], filter['dateEnd'])
        if (filter.has_key('custId')):
            filterSql += ' and custId=%d' %filter['custId']
            
        saleOrderListRef = CDataSaleOrder.fetch(filterSql)
        if (saleOrderListRef is None):
            return 0
        
        for saleOrder in (saleOrderListRef):
            index = self.InsertStringItem(sys.maxint, '')
            dataRow = []
            dataRow.append(saleOrder.getFieldVal('id'))
            if (filter.has_key('custId')):
                dataRow.append(filter['custName'])
            else:
                cust = CDataCustomer.getData({'id':saleOrder.getFieldVal('custId')})
                if cust is None:
                    print 'Error:None cust %d' %saleOrder.getFieldVal('custId')
                    dataRow.append('None')
                else:
                    dataRow.append(cust.getFieldVal('name'))
            
            dataRow.append(saleOrder.getFieldVal('total'))
            dataRow.append(saleOrder.getFieldVal('paid'))
            dataRow.append(saleOrder.getFieldVal('unpaid'))
            dataRow.append(saleOrder.getFieldVal('discount'))
            dataRow.append(saleOrder.getFieldVal('billDate'))
            # dlvyId = saleOrder.getFieldVal('dlvyId')
            # dataRow.append(
            #     CDataDelivery.getFirstFieldVal({'id':dlvyId},'name'))#Get from other table
            dataRow.append(saleOrder.getFieldVal('dlvyInfo'))
            dataRow.append(saleOrder.getFieldVal('memo'))
            dataRow.append(saleOrder.getFieldVal('handlerId'))
            dataRow.append(saleOrder.getFieldVal('recorderId'))
            #print dataRow
            for i in range(len(dataRow)):
                val = dataRow[i]
                if (val == None):
                    val = ''
                if (type(val) != str and type(val) != unicode):
                    val = str(val)
                
                self.SetStringItem(index, i, val)   
            
            self.SetItemData(index, index)
            self.itemDataMap[index]=dataRow
             
        return len(saleOrderListRef)
    
    # Used by the ColumnSorterMixin   
    def GetListCtrl(self):
        return self
        
class MySortListCtrl(wx.ListCtrl, listmix.ColumnSorterMixin):
    '''自定义可排序的列表，该列表缓存列表中显示的所有数据
        子类需重新定义cols[], convert()
    '''

    # 实际上以下标记也没有什么用，可以删除只需要声明空函数即可，子类根据需要重载
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = False
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = False
    xlsFile = u'列表导出数据(未命名).xlsx'
    
    defSortCol = -1
    defSortAscending = 1
    
    def __init__(self, parent, pos=wx.DefaultPosition,size=wx.DefaultSize, 
                style=wx.LC_HRULES | wx.LC_VRULES | wx.LC_REPORT | wx.LC_SINGLE_SEL):
        wx.ListCtrl.__init__(self, parent=parent, pos=pos, size=size, style=style)

        self.SetBackgroundColour(wx.Colour(164, 242, 189))
        self.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL,
              wx.NORMAL, False, u'Times New Roman'))
              
        self.initColHeader()      
        
        listmix.ColumnSorterMixin.__init__(self, len(self.cols))
    
        self.il = wx.ImageList(16, 16)
        self.sm_up = self.il.Add(SmallUpArrow.GetBitmap())
        self.sm_dn = self.il.Add(SmallDnArrow.GetBitmap())
        self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
      
        if (self.include_menu):
            self.initRightMenu()
        
        if (self.include_statBar):
            self.initStatBar()
        
        self.itemDataMap = {}
        #self.Bind(wx.EVT_SIZE, self.OnListSize)
        self.Bind(wx.EVT_PAINT, self.OnListPaint)
        
    def initRightMenu(self):
        self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)
        
        self.menu = wx.Menu()
        
        self.makeMenu()
    
    def makeMenu(self):
        '''由子类重载该函数，以定制菜单。
            可以在子类中调用appendCommonMenu以默认添加以下菜单'''
        pass
    
    def appendCommonMenu(self):
        item = self.menu.Append(-1, u'刷新列表')
        self.Bind(wx.EVT_MENU, self.OnMenuRefresh, item)   
              
        item = self.menu.Append(-1, u'导出到excel')
        self.Bind(wx.EVT_MENU, self.OnMenuExport, item)
    
    def appendMenuRefresh(self, label, handler):
        item = self.menu.Append(-1, label)
        self.Bind(wx.EVT_MENU, handler, item)
    
    def appendMenuFilter(self):
        item = self.menu.Append(-1, u'筛选显示')
        self.Bind(wx.EVT_MENU, self.OnMenuFilter, item)   
        
    def appendMenuShowProDetail(self):
        '''要求子类实现getProId(item=-1)'''
        item = self.menu.Append(-1, u'查阅商品进销')
        self.Bind(wx.EVT_MENU, self.OnMenuShowProDetail, item)   
    
    def appendMenuShowProImage(self):
        '''要求子类实现getProId(item=-1)'''
        item = self.menu.Append(-1, u'查看商品图片')
        self.Bind(wx.EVT_MENU, self.OnMenuShowProImage, item) 

    def appendMenuModifyQty(self):
        '''要求子类实现getProId(item=-1)'''
        item = self.menu.Append(-1, u'修改仓位库存')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyQty, item)


    def OnPopupMenu(self, event):
        '''商品分类右键弹出菜单处理'''
        pos = self.ScreenToClient(event.GetPosition())
        self.PopupMenu(self.menu, pos)
    
    def OnMenuShowProDetail(self, event):
        import PanelProductVariation
        
        proId = self.getProId()
        if proId == -1:
            return
        
        dlg = wx.Dialog(self, -1, u'产品进销明细')
        panel = PanelProductVariation.PanelProductVariation(dlg)
        panel.setData(proId, self.getPeerId() if hasattr(self, "getPeerId") else None)
        dlg.SetClientSize(panel.GetSize())
        dlg.CenterOnScreen()
        dlg.ShowModal()
        dlg.Destroy()
    
    def OnMenuShowProImage(self, event):
        import DlgProductImage
        
        proId = self.getProId()
        if proId == -1:
            return
        
        dlg = DlgProductImage.create(self)
        dlg.SetProduct(proId)
        dlg.ShowModal()    
            
    def OnMenuModifyQty(self, event):
        import DlgProductStock
        
        proId = self.getProId()
        if proId == -1:
            return
        dlg = DlgProductStock.create(self)
        dlg.SetProduct(proId)
        ret = dlg.ShowModal()

    def OnMenuFilter(self, event):
        dlg = wx.TextEntryDialog(self, u'请输入过滤词：',
                                u'提示', u'',wx.OK|wx.CANCEL|wx.CENTRE)
        if dlg.ShowModal() != wx.ID_OK:
            return
        self.refreshView(dlg.GetValue())
        
    def OnMenuRefresh(self, event):
        self.reloadData()
    
    def OnMenuNewOrder(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if item == -1:
            #p = kit.getRootWin(self).newSaleOrder()
            #p.setDeliveryPlan(self.GetParent().getPlanId())
            pass
        else:
            custId = self.getPeerId(item)
            custObj = CDataCustomer.getData({'id':custId})#.findObj(custId)
            p = kit.getRootWin(self).newSaleOrder()
            p.setSelectPeer(custObj)
            #p.setDeliveryPlan(self.GetParent().getPlanId())

    def OnMenuAddLog(self, event):
        ''' 添加客情 '''
        import DlgAddCustomerLog
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        dlg = DlgAddCustomerLog.create(self)
        dlg.setData(self.getPeerId(item))
        dlg.ShowModal()
        
        peerObj = CDataCustomer.getData({'id':self.getPeerId(item)})
        self.SetStringItem(item, self.iLog, peerObj.getValue(peerObj.COL_LMMEMO))  

    def OnMenuEditCustmor(self, event):
        '''编辑客户'''
        import DlgCustomerEditor

        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        dlg = DlgCustomerEditor.create(self)
        dlg.setData(self.getPeerId(item))
        dlg.ShowModal()

    def OnMenuShowImage(self, event):
        import DlgProductImage
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = DlgProductImage.create(self)
        dlg.SetCustomer(self.getPeerId(item))
        dlg.ShowModal()

    def OnMenuVoucherDlg(self, event):
        import DlgVoucher

        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        dlg = DlgVoucher.DlgVoucher(self, DlgVoucher.Type_Customer)
        saleId = self.getBillId(item)#self.tBillId.GetLabel()
        #saleId = self.m_billObj.getValue(self.m_billObj.COL_ID)
        dlg.setBill(saleId, False)
        #dlg.setCustMode(self.customer, self.tcYingShou.GetValue(), self.TSOID.GetLabel())
        if(dlg.ShowModal() == wx.ID_CANCEL):
            return
        self.refreshItem(item)

    @classmethod
    def getXlsFileName(cls):
        return cls.xlsFile
    
    def OnMenuExport(self, event):
        if not PermitManager.accessTest(const.PERMIT_EXPORT):
            return
        
        #dlg = wx.TextEntryDialog(self, u'请输入文件名，注意如果当前目录下存在同名文件，该同名文件将被覆盖',
        #                        u'提示',self.getXlsFileName(),wx.OK|wx.CANCEL|wx.CENTRE)
        
        dlg = wx.FileDialog(
            self, message="Save file as ...", defaultDir=os.getcwd(), 
            defaultFile="%s"%self.getXlsFileName(), wildcard='*.xlsx', style=wx.SAVE
            )
        
        if dlg.ShowModal() != wx.ID_OK:
            return
        
        file = dlg.GetPaths()[0]
        print file
        if(kit.exportList(self, file) < 0):
            msg = u'数据导出失败，请查看是不是其他程序中打开了该文件！'
        else:
            msg = u'数据完成导出'
            
        dlg = wx.MessageDialog(self, msg, u'提示',wx.OK|wx.ICON_INFORMATION)
        dlg.ShowModal()
            
    def initColHeader(self):
        # 作为基类，目标是
        self.cols = []
        self.makeCols() # 由子类覆盖(使用接口appendCol())，尽量减少子类代码
        for i in range(len(self.cols)):
            self.InsertColumn(i, self.cols[i][0], self.cols[i][1], self.cols[i][2])
    
    def makeCols(self):
        '''子类初始化垒头数据'''
        pass
        
    def appendCol(self, colInfo):
        '''colInfo - (heading, format, width)'''
        self.cols.append(colInfo)
        return len(self.cols) - 1
    
    def appendColList(self, cols):
        '''colInfo - ((heading, format, width),)'''
        index = []
        for item in cols:
            self.cols.append(item)
            index.append(len(self.cols) - 1)
        
        return index
        
    # Used by the ColumnSorterMixin   
    def GetListCtrl(self):
        return self
    
    # Used by the ColumnSorterMixin
    def GetSortImages(self):
        return (self.sm_dn, self.sm_up)

    def refreshStatBar(self):
        self.resetStatValue()
        self.resetStatPos()
        
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        pass
    
    def setStatSum(self, cols):
        '''对指定列求和'''
        
        for col in cols:
            sum = 0.0
            for row in range(self.GetItemCount()):
                val = self.GetItem(row, col).GetText()
                if (val != ''):
                    sum += float(val)
            self.tStatList[col].SetLabel(kit.toStr(sum))#(kit.myStr(sum))
            
    def resetStatPos(self):
        itemHeight = self.GetItemRect(0).GetHeight()
        
        posX = 0
        posY = self.GetClientSize().GetHeight() - itemHeight
        for i in range(len(self.cols)):
            self.tStatList[i].Move((posX, posY+4))
            self.tStatList[i].SetSize(wx.Size(self.GetColumnWidth(i)-1, itemHeight))
            posX += self.GetColumnWidth(i)
            
    def initStatBar(self):
        '''
            初始化listctrl统计栏，由子类选择是否初始化
            如果使用统计栏，则在init时调用initStatBar，并覆写resetStatValue
        '''
        self.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnListColEndDrag)
              
        self.tStatList = []
        for i in range(len(self.cols)):
            txt = wx.StaticText(self, -1, "", style=wx.ALIGN_RIGHT)
            txt.SetBackgroundColour(wx.Colour(0, 255, 255))
            self.tStatList.append(txt)
            
    def OnListColEndDrag(self, event):
        self.resetStatPos()
    
    def convert(self, filter={}):
        '''根据filter转换数据库数据为列表数据
            filter - {'xx':xx,}
            return - data转换后的二维列表数组
        '''
        
        data = []
        
        #fill data[]
        
        return data
    
    def refreshView(self, val):
        '''
            在当前列表中，根据搜索条件，删除掉不符合条件的项，但不改变过滤条件
            该函数的问题是：lc中的item已经被删除了，重新搜索需要重新refresh
            相对而言，重设过滤条件，需要仔细设计并增加不少代码（主要是子类的设计，
            对应多张表的lc不具备共性）
            val - string 要匹配的值
        '''
        
        if not(self.listAll):
            self.reloadData()
            
        # 循环中删除会导致混乱，改为倒序循环删除
        #for row in range(self.GetItemCount())
        for row in range(self.GetItemCount()-1, -1, -1):
            hit = False
            for col in range(self.GetColumnCount()):
                text = self.GetItem(row, col).GetText()
                if (text.upper().find(val.upper()) >= 0):
                    hit = True
            if not (hit):
                self.DeleteItem(row)
                self.listAll = False        
                
    def refreshFullField(self, val):
        '''
            重设过滤条件，从数据库中所有字段搜索匹配数值，该函数可以直接用
            refresh({'all':val})实现，对于'all'的函数实现，基本信息显示列表可以有
            相似的实现方式
        '''
        pass
    
    def resetBgcolour(self, row):
        if(row%2 == 0):
            self.SetItemBackgroundColour(row, wx.Colour(128, 255, 128))
        else:
            self.SetItemBackgroundColour(row, wx.Colour(164, 242, 189))
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            self.resetBgcolour(index)
    
    def reloadData(self):
        if 'curFilter' in dir(self):
            self.refresh(self.curFilter)
        else:
            self.refresh()
    
    def reloadItem(self, item):
        '''子类通过覆盖实现该函数实现条目刷新'''
        pass
    
    def convert2str(self, val):
        if (val is None):
            val = ''
        #if (type(val) == float):
        #    val = '%g' %val
        if (type(val) != str and type(val) != unicode):
            val = str(val)
        return val
            
    def refreshItem(self, item):
        dataList = self.reloadItem(item)
        for i in range(len(dataList)):
            self.SetStringItem(item, i, self.convert2str(dataList[i]))    
            
    def refresh(self, filter={}):
        '''根据具体列表，产生并填充数据，必须重载
            return - cnt of listData
        '''
        # for refreshView().
        # if refreshView() called repeatedly, it is used to recover lc.
        self.curFilter = filter
        self.listAll = True
        
        self.DeleteAllItems() 
        self.itemDataMap = {}
  
        data = self.convert(filter)
##        if (len(data) == 0):
##            return 0
        
        #print data
        for row in range(len(data)):
            #print row
            #print self.GetItemCount()
            index = self.InsertStringItem(sys.maxint, '')
            if (index != row):
                raise Exception()
            for col in range(len(data[row])):
                val = data[row][col]
                #print(val)
                if (val == None):
                    val = ''
                
                val = kit.toStr(val)
                # if isinstance(val, float):
                #     if abs(val) > 10000:
                #         val = '%.2f' %val
                #         val = val.rstrip('0')
                #         val = val.rstrip('.')
                #     else:
                #         val = '%g' %val # 超过10000，就会丢失精度，如 17724.36 转换为 17724.4
                #         #print('g', val)
                
                # if (type(val) != str and type(val) != unicode):
                #     val = str(val)
                #     #print('str', val)

                    
                self.SetStringItem(row, col, val)   
            
            self.SetItemData(row, row)
            #虽然data是局部变量，但是python是垃圾自动回收，由于该数据有引用，
            #所以根据一般原理，该数据区域不会被回收
            #如果出现问题，可以使用self.data，不过为了验证设想，使用局部变量
            self.itemDataMap[row]=data[row]  
        
        self.refreshBgColour()
        
        # 140815
        if (self.include_statBar):
            self.refreshStatBar()
##            self.resetStatValue()
##            # 初始化时，因为listctrl没有数据，所以statBar的大小有问题，不显示
##            # 在刷新出数据时，重设位置
##            self.resetStatPos()
        
        # 默认排序
        if self.defSortCol != -1:
            self.SortListItems(self.defSortCol, self.defSortAscending)
    
        #self.resizeClient() # 无 效
        return len(data)

    def resizeClient(self):
        print 'resizeClient'
        print self.GetSize()
        print self.GetClientSize()
        #print self.DoGetBestSize()
        print self.GetBestSize()
        print self.GetMaxSize()
        print self.GetMinSize()
        print self.GetCountPerPage()
        print self.GetScrollRange(wx.VERTICAL)
        
        rect = self.GetClientSize()
        #self.SetClientSize(wx.Size(rect.width, rect.height+50))
        #self.CacheBestSize(wx.Size(rect.width, rect.height+50))
        #self.SetScrollbar(wx.VERTICAL, 0, self.GetCountPerPage(),self.GetScrollRange(wx.VERTICAL)+10)
        self.SetScrollbar(wx.VERTICAL, self.GetScrollPos(wx.VERTICAL), self.GetCountPerPage(),self.GetItemCount()+10)
        print '----'
        print self.GetSize()
        print self.GetClientSize()
        #print self.DoGetBestSize()
        print self.GetBestSize()
        print self.GetMaxSize()
        print self.GetMinSize()
        print self.GetCountPerPage()
        print self.GetScrollRange(wx.VERTICAL)
    
    def OnListPaint(self, event):
        #print 'OnListPaint'
        self.SetScrollbar(wx.VERTICAL, self.GetScrollPos(wx.VERTICAL), self.GetCountPerPage(),self.GetItemCount()+5)
        # 滑动窗口会移动listCtrl的大小位置，statBar的显示会出问题
        if self.include_statBar:
            self.resetStatPos()
        event.Skip()
    
##    def OnListSize(self, event):
##        print 'OnListSize'
##        self.SetScrollbar(wx.VERTICAL, self.GetScrollPos(wx.VERTICAL), self.GetCountPerPage(),self.GetItemCount()+10)
##        event.Skip()
        
    def OnSortOrderChanged(self):
        #print 'OnSortOrderChanged'
        #print (col, ascending)
        #super(listmix.ColumnSorterMixin, self).SortListItems(col, ascending)
        #super(listmix.ColumnSorterMixin, self).OnSortOrderChanged()
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        #print (type(item), item)
        self.EnsureVisible(long(item))
        #rect = self.GetItemRect(item)
        #print (item, rect)
        #self.ScrollList(0, rect.y)
        #self.SetScrollbar(wx.VERTICAL, 0, self.GetCountPerPage(),self.GetScrollRange(wx.VERTICAL)+10)
    
    def swapItem(self, item1, item2):
        for col in range(self.GetColumnCount()):
            temp = self.GetItem(item1, col).GetText()
            self.SetStringItem(item1, col, self.GetItem(item2, col).GetText())
            self.SetStringItem(item2, col, temp)

    def InsertRow(self, row_data, index = -1):
        '''添加一行数据
            row_data - [,,,]
        '''
        if index == -1:
            index = self.InsertStringItem(sys.maxint, '')
        for i,val in enumerate((row_data)):      
            if (val is None):
                val = ''
            if isinstance(val, float):
                if val > 10000:
                    val = '%.2f' %val
                    val = val.rstrip('0')
                    val = val.rstrip('.')
                else:
                    val = '%g' %val
            if (type(val) != str and type(val) != unicode):
                val = str(val)
            
            self.SetStringItem(index, i, val)
        
        self.SetItemData(index, index)
        self.itemDataMap[index]=row_data 
            
class MySimpleListCtrl(MySortListCtrl):
    '''简单呈现单个数据表的某些字段，不处理复杂逻辑'''
    
    # @classmethod
    # def factory(cls, parent, dataCls, showCols):
    #     '''
    #         工厂方法
    #         dataCls - CDataXXX   数据模型
    #         showCols - [(col_index, format, width),] 行模式
        
    #     '''
    #     cls.showCols = showCols
    #     cls.dataCls = dataCls
        
    #     return cls(parent)

    def __init__(self, parent, dataCls, showCols):
        self.showCols = showCols
        self.dataCls = dataCls
        super(MySimpleListCtrl, self).__init__(parent)
    
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuFilter(self)

        self.menu.AppendSeparator()

        self.appendCommonMenu()
        
    def makeCols(self):
        for fi_col,format,width in self.showCols:
            self.appendCol((self.dataCls.getCNName(index=fi_col), format, width))
    
    def getData(self, row, fi_col):
        for index in range(len(self.showCols)):
            if self.showCols[index][0] == fi_col:
                return self.GetItem(row, index).GetText()
        
        print ('Error: unknown row ', row, ' col ', fi_col)
        return ''
    
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - 无，全部显示
        '''
        #print(self.dataCls.__name__)
        dataList = []
        
        for obj in self.dataCls.getObjList():
            
##            if not(self.checkShow(obj)):
##                continue
            dataRow = []
            for fi_col,format,width in self.showCols:
                dataRow.append(obj.getValue(fi_col))
                
            dataList.append(dataRow)
            
        return dataList

                    
class MyProductListCtrl(MySortListCtrl):
    '''在container中初始化列表，缺陷是只能处理对应单个数据表的数据，
        不能处理涉及多个数据表的情况
    '''
    include_menu = True
    
    def __init__(self, parent, style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES):
        
        self.filterSql = ''
        self.filter_keywordIds = []
        self.filter_categoryIds = []
        
        #由于父类还没有初始化，所以Bind()还没有继承到
##        #右键菜单
##        self.initMenu()
                       
        MySortListCtrl.__init__(self, parent=parent, style=style)
        
        #右键菜单
        #self.initMenu()
    
        # 显示类型
        self.viewAll = 0
        self.viewSale = 1
        self.viewPur = 2
        self.viewType = self.viewAll
        
        self.showUnused = False
        self.m_showInventory = False
    
    def makeCols(self): 
        self.iId = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'品名', wx.LIST_FORMAT_LEFT, 200))
        #self.iBriefCode = self.appendCol((u'简码', wx.LIST_FORMAT_LEFT, 0))

        self.iZZ2 = self.appendCol((u'商品名称', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ3 = self.appendCol((u'一级商品分类', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ4 = self.appendCol((u'二级商品分类', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ5 = self.appendCol((u'三级商品分类', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ6 = self.appendCol((u'规格组', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ14 = self.appendCol((u'规格值', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ19 = self.appendCol((u'上下架状态', wx.LIST_FORMAT_RIGHT, 0))

        self.iCategory = self.appendCol((u'类型', wx.LIST_FORMAT_LEFT, 0))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 200))
        #self.iBrand = self.appendCol((u'品牌', wx.LIST_FORMAT_LEFT, 0))
        self.iWeight = self.appendCol((u'重量', wx.LIST_FORMAT_LEFT, 45))
        self.iOnuse = self.appendCol((u'启用', wx.LIST_FORMAT_LEFT, 0))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 45))
        #self.iCost = self.appendCol((u'预设成本', wx.LIST_FORMAT_RIGHT, -1))
        #self.iMinMaxPurPrice = self.appendCol((u'最低/最高进价', wx.LIST_FORMAT_RIGHT, 0))
        self.iWH1 = self.appendCol((u'金博', wx.LIST_FORMAT_RIGHT, 50))
        #self.iStock2 = self.appendCol((u'库存数量2', wx.LIST_FORMAT_RIGHT, 0))
        #self.iStock3 = self.appendCol((u'库存数量3', wx.LIST_FORMAT_RIGHT, 0))
        self.iBulkPrice = self.appendCol((u'批发价', wx.LIST_FORMAT_RIGHT, 70))
        self.iLxPrice = self.appendCol((u'自提底价', wx.LIST_FORMAT_RIGHT, 70))
        self.iFloorPrice = self.appendCol((u'送货底价', wx.LIST_FORMAT_RIGHT, 70))
        self.iCostPrice = self.appendCol((u'入库价', wx.LIST_FORMAT_RIGHT, 0))
        self.iLastPurPrice = self.appendCol((u'最近进价', wx.LIST_FORMAT_RIGHT, 0)) # 采购选择商品时需要这一列
        #self.iPosition = self.appendCol((u'仓位', wx.LIST_FORMAT_RIGHT, 50))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 100))
        self.iWH1_POS = self.appendCol((u'金博仓', wx.LIST_FORMAT_RIGHT, 50))
        self.iStock = self.appendCol((u'总库存', wx.LIST_FORMAT_RIGHT, 60))
        self.iWH2_POS = self.appendCol((u'武鸣仓', wx.LIST_FORMAT_RIGHT, 0))
        self.iWH2 = self.appendCol((u'武鸣', wx.LIST_FORMAT_RIGHT, 50))
        self.iWH3_POS = self.appendCol((u'五一仓', wx.LIST_FORMAT_RIGHT, 0))
        self.iWH3 = self.appendCol((u'五一', wx.LIST_FORMAT_RIGHT, 50))
        self.iWarnStock = self.appendCol((u'预警线', wx.LIST_FORMAT_RIGHT, 0))
        self.iPrice = self.appendCol((u'平台价格', wx.LIST_FORMAT_RIGHT, 70))
        self.iMallRefPrice = self.appendCol((u'参照', wx.LIST_FORMAT_RIGHT, 70))
        self.iMallDiff = self.appendCol((u'差额', wx.LIST_FORMAT_RIGHT, 70))

        self.iZZ1 = self.appendCol((u'商品编号', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ7 = self.appendCol((u'零售价', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ8 = self.appendCol((u'VIP批发价', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ9 = self.appendCol((u'SVIP五金店', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ10 = self.appendCol((u'SSVIP优质客户', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ11 = self.appendCol((u'SSSVIP二批老乡', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ12 = self.appendCol((u'参考采购价', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ13 = self.appendCol((u'最低售价', wx.LIST_FORMAT_RIGHT, 0))        
        self.iZZ15 = self.appendCol((u'规格备注1', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ16 = self.appendCol((u'规格备注2', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ17 = self.appendCol((u'金博仓-期初库存', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ18 = self.appendCol((u'金博仓-成本均价', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ17 = self.appendCol((u'五一仓-期初库存', wx.LIST_FORMAT_RIGHT, 0))
        self.iZZ18 = self.appendCol((u'五一仓-成本均价', wx.LIST_FORMAT_RIGHT, 0))
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if hasattr(self, "iOnuse") and self.GetItem(index, self.iOnuse).GetText() != 'O':
                self.SetItemBackgroundColour(index, wx.Colour(250, 140, 217)) # 紫色
            elif hasattr(self, "iStock") and float(self.GetItem(index, self.iStock).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            elif hasattr(self, "iStock") and hasattr(self, "iWarnStock") and float(self.GetItem(index, self.iStock).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)           
        
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iId).GetText())
    
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'添加新商品')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item) 
        self.MENU_ADD = item.GetId()
        
        item = self.menu.Append(-1, u'复制新增')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
        self.MENU_COPY = item.GetId()
        
        self.menu.AppendSeparator()
              
        item = self.menu.Append(-1, u'修改选中产品')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
        self.MENU_MODIFY = item.GetId()
        
        item = self.menu.Append(-1, u'禁用选中产品')
        self.Bind(wx.EVT_MENU, self.OnMenuDisable, item)
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'删除选中产品')
            self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)  
            self.MENU_DEL = item.GetId()
        
        self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'修改商品库存')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
        self.MENU_EDIT_QTY = item.GetId()

        self.menu.AppendSeparator()

        
        item = self.menu.Append(-1, u'隐藏该项')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)  
        self.MENU_HIDE = item.GetId()
        
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)

    def initMenu_obsolete(self):
        self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)   
              
        #右键菜单
        self.menu = wx.Menu()
##        self.menuList = [u'添加新商品', u'复制新增', u'修改', u'删除', u'隐藏该项']
##        [self.MENU_ADD, self.MENU_COPY,self.MENU_MODIFY, self.MENU_DEL, self.MENU_HIDE] = \
##            [i for i in range(len(self.menuList))]
##
##        for text in self.menuList:
##            item = self.menu.Append(-1, text)
##            self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
        
        item = self.menu.Append(-1, u'添加新商品')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item) 
        self.MENU_ADD = item.GetId()
        
        item = self.menu.Append(-1, u'复制新增')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
        self.MENU_COPY = item.GetId()
        
        self.menu.AppendSeparator()
              
        item = self.menu.Append(-1, u'修改选中产品')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
        self.MENU_MODIFY = item.GetId()
        
        item = self.menu.Append(-1, u'禁用选中产品')
        self.Bind(wx.EVT_MENU, self.OnMenuDisable, item)
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'删除选中产品')
            self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)  
            self.MENU_DEL = item.GetId()
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'隐藏该项')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)  
        self.MENU_HIDE = item.GetId()
        
    def setShowUnused(self, showUnused):
        self.showUnused = showUnused
    
    def setShowInventory(self, showInventory):
        self.m_showInventory = showInventory
        
    def setViewProSelect(self, viewType):
        self.viewType = viewType
        
        if(self.viewType == self.viewSale):
            self.SetColumnWidth(self.iId, 0)
            #self.SetColumnWidth(self.iBriefCode, 0)
            self.SetColumnWidth(self.iCategory, 0)
            #self.SetColumnWidth(self.iBrand, 0)
            self.SetColumnWidth(self.iOnuse, 0)
            self.SetColumnWidth(self.iName, 130)
            self.SetColumnWidth(self.iSpec, 130)
            #self.SetColumnWidth(self.iCost, 0)
            self.SetColumnWidth(self.iLastPurPrice, 0)
            self.SetColumnWidth(self.iWeight, 0)
                
        elif(self.viewType == self.viewPur):
            self.SetColumnWidth(self.iId, 0)
            #self.SetColumnWidth(self.iBriefCode, 0)
            self.SetColumnWidth(self.iCategory, 0)
            #self.SetColumnWidth(self.iBrand, 0)
            self.SetColumnWidth(self.iOnuse, 0)
            self.SetColumnWidth(self.iPrice, 0)
            #self.SetColumnWidth(self.iCost, 0)
            self.SetColumnWidth(self.iName, 130)
            self.SetColumnWidth(self.iSpec, 130)
            self.SetColumnWidth(self.iBulkPrice, 0)
            self.SetColumnWidth(self.iLxPrice, 0)
            self.SetColumnWidth(self.iFloorPrice, 0)
            self.SetColumnWidth(self.iWeight, 0)
            self.SetColumnWidth(self.iLastPurPrice, 70)
            
        else:
            pass
            
    def OnPopupMenu(self, event):
        '''商品分类右键弹出菜单处理'''
        print 'OnPopupMenu'

        pos = self.ScreenToClient(event.GetPosition())
        self.PopupMenu(self.menu, pos)

    def OnMenuDisable(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.MessageDialog(self, u'是否禁用该产品?', u'提示',
                                    wx.YES_NO|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return
                
        proObj = self.getObj(item)
        proObj.enable(False)
        
    def OnPopupMenuSelected(self, event):
        import DlgEditPro
        
        menuItem = self.menu.FindItemById(event.GetId())
        print menuItem.GetText()
        print menuItem.GetId()
        
        item = None
        
        #if (menuItem.GetText() == self.menuList[self.MENU_ADD]):
        if (menuItem.GetId() == self.MENU_ADD):
            dlg = DlgEditPro.create(self)
            ret = dlg.ShowModal()
        
        elif (menuItem.GetId() == self.MENU_COPY):
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return

            proObj = self.getObj(item)
            if (proObj is None):
                print 'Error'
            dlg = DlgEditPro.create(self)
            dlg.setData(proObj, True)
            ret = dlg.ShowModal()
            
        elif (menuItem.GetId() == self.MENU_MODIFY):
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return

            proObj = self.getObj(item)
            
            dlg = DlgEditPro.create(self)
            dlg.setData(proObj)
            ret = dlg.ShowModal()
            self.refreshItem(item)
            
        elif (menuItem.GetId() == self.MENU_DEL):
            #删除一个产品，要保证尚未参与购销
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return
            
            dlg = wx.MessageDialog(self, u'是否确认删除该产品？',u'提示',
                                    wx.YES_NO|wx.ICON_QUESTION)
            if(dlg.ShowModal() == wx.ID_NO):
                return

            proObj = self.getObj(item)
            
            if(proObj.delete() > 0):
                ret = wx.ID_OK
##            if (proObj.isDeletable()):
##                proObj.delete()
##                ret = wx.ID_OK
            else:
                dlg = wx.MessageDialog(self, u'该产品已参与购销，不能删除',u'提示',
                                    wx.OK|wx.ICON_ERROR)
                dlg.ShowModal()
                ret = wx.ID_CANCEL

        elif (menuItem.GetId() == self.MENU_HIDE):
            # hide the item
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return
            self.DeleteItem(item)
            ret = wx.ID_OK
        
        elif (menuItem.GetId() == self.MENU_EDIT_QTY): # 修改库存
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return
            proId = int(self.GetItemText(item))
            
            import DlgProductStock
            dlg = DlgProductStock.create(self)
            dlg.SetProduct(proId)
            ret = dlg.ShowModal()
            self.refreshItem(item)

        else:
            logger.debug('unkown item %s', menuItem.GetText())
            #print ''
            
        if (ret == wx.ID_OK):
            #must reset filter for that filterSql was timeout
            self.setFilter(self.filter_keywordIds, self.filter_categoryIds)
            #self.refresh()
            #self.SelectItem(item)
    
    def getObj(self, item):
        proId = int(self.GetItemText(item))
        return CDataProduct.getFirstInstance({CDataProduct.COL_ID:proId})
    
    def getSelectObj(self):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return None
        
        return self.getObj(item)
    
    def getProSaleInfo(self, item=-1):
        if (item == -1):
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return []
            
        proId = int(self.GetItem(item, self.iId).GetText())
        proName = self.GetItem(item, self.iName).GetText()
        unit = self.GetItem(item, self.iUnit).GetText()
        
        if(self.viewType == self.viewSale):
            # 不再使用预设售价，改为预设售价与批发价较大的一个
            price = max(float(self.GetItem(item, self.iPrice).GetText()), float(self.GetItem(item, self.iBulkPrice).GetText())) 
        elif(self.viewType == self.viewPur):
            price = float(self.GetItem(item, self.iLastPurPrice).GetText())
            
        return [proId, proName, unit, price]
       
    def concat(self, list, separator):
        str = ''
        for i in range(len(list)):
            str += '%d,' %list[i]
    
        return str[:-1]
    
    def setFilter(self, keywordIds=[], categoryIds=[], sku=((),())):
        '''转换条件为sql形式'''
        
        self.filter_keywordIds = keywordIds
        self.filter_categoryIds = categoryIds
        self.filterSql = ''
        
        #根据关键字查找proId
        if (len(keywordIds) != 0):
##            proIds = []
##            sql = 'keywordId in (' + self.concat(keywordIds, ',') +')'
##            proLabelObjs = CDataProLabel.fetch(sql)
##            for obj in proLabelObjs:
##                proIds.append(obj.getFieldVal(index=CDataProLabel.COL_PROID))
        
            proIds = CDataProLabel.getProId(keywordIds, True)
            if (len(proIds) != 0):
                self.filterSql += 'id in (' + self.concat(proIds, ',') + ')'
            else:
                #没有符合关键字的产品，应该不显示数据
                self.filterSql += 'id in (0)'
            
        #根据分类查找    
        if (len(categoryIds) != 0):
            if (self.filterSql != ''):
                self.filterSql += ' and '
            self.filterSql += 'categoryId in (' + self.concat(categoryIds, ',') + ')'
        
        print sku
        if (len(sku[1]) > 0):
            print sku[1]
            sku_item = tuple([",".join(i) for i in sku[1]])
            # if len(sku[1][0]) == 1:
                # sku_item = sku[1]
            # else:
                # sku_item = tuple([",".join(i) for i in sku[1]])
            print sku_item
            if (self.filterSql != ''):
                self.filterSql += ' and '
            self.filterSql += " product.id IN "\
                " (SELECT pro_id FROM ("\
                " SELECT pro_id,GROUP_CONCAT(sku_id ORDER BY group_id) as sku"\
                " FROM product_sku LEFT JOIN sku_item ON sku_id=sku_item.id"\
                " WHERE group_id IN (%s)"\
                " GROUP BY pro_id ) t WHERE sku in %s)" \
                %(",".join([str(i) for i in sku[0]])
                 , str(sku_item).replace("u'","'") if len(sku_item) > 1 else "('%s')"%sku_item)
            
            
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'keyword':, 'category':}
        '''

        #return CDataProduct.get_pro_list('' if len(filter) == 0 else self.filterSql, 
        #    self.showUnused, self.m_showInventory)

        dataList = []
        if (len(filter) == 0):
            filterSql = self.filterSql
        else:
            log(ERR, 'Undo')
            filterSql = ''
        
        if (not self.showUnused):
            filterSql += " " if filterSql == '' else " AND " + " onUse=1 "
        if (self.m_showInventory):
            filterSql += " " if filterSql == '' else " AND " + " onhand1>0 "

        return CDataProduct.get_pro_list(filterSql.strip())

        objList = CDataProduct.fetch(filterSql.strip())
        for obj in objList:
            # if (not obj.isOnuse()) and (not self.showUnused):
            #     continue
                
            # if (self.m_showInventory and obj.getFieldVal(index=CDataProduct.COL_ONHAND1) <= 0):
            #     continue
                
            dataRow = []
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_ID))
            
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_NAME))
            #dataRow.append(obj.getFieldVal(index=CDataProduct.COL_BRIEFCODE))
            categoryId = obj.getFieldVal(index=CDataProduct.COL_CATEGORYID)
            categoryObj = CDataCategory.getData({"id":categoryId})#getFirstInstance({CDataCategory.COL_ID:categoryId})
            categoryName = categoryObj.getFieldVal(index=CDataCategory.COL_NAME)
            dataRow.append(categoryName)
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_SPEC))
            #dataRow.append(obj.getFieldVal(index=CDataProduct.COL_BRAND))
            
            if (obj.isOnuse()):
                dataRow.append('O')
            else:
                dataRow.append('X')
                
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_UNIT1))
                        
            #str = '%g' %obj.getFieldVal(index=CDataProduct.COL_DEFSALE1)
            #dataRow.append(str)
            #str = '%g' %obj.getFieldVal(index=CDataProduct.COL_DEFCOST1)
            #dataRow.append(str)
            #str = '%g' %obj.getFieldVal(index=CDataProduct.COL_LASTPUR1)
            #dataRow.append(str)

            # str = '%g' %(obj.getFieldVal(index=CDataProduct.COL_LASTPUR1) + obj.getFieldVal(index=CDataProduct.COL_WHOLE_PROFIT))
            # dataRow.append(str)
            # str = '%g' %(obj.getFieldVal(index=CDataProduct.COL_LASTPUR1) + obj.getFieldVal(index=CDataProduct.COL_LX_PROFIT))
            # dataRow.append(str)
            # str = '%g' %(obj.getFieldVal(index=CDataProduct.COL_LASTPUR1) + obj.getFieldVal(index=CDataProduct.COL_MINPROFIT))
            # dataRow.append(str)
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_LASTPUR1) + obj.getFieldVal(index=CDataProduct.COL_WHOLE_PROFIT))
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_LASTPUR1) + obj.getFieldVal(index=CDataProduct.COL_LX_PROFIT))
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_LASTPUR1) + obj.getFieldVal(index=CDataProduct.COL_MINPROFIT))

            #str = '%g' %obj.getFieldVal(index=CDataProduct.COL_MINPUR1)
            #dataRow.append(str)
            #str = '%g' %obj.getFieldVal(index=CDataProduct.COL_MAXPUR1)
            #dataRow.append(str)
            str = '%g/%g' %(obj.getFieldVal(index=CDataProduct.COL_MINPUR1),
                            obj.getFieldVal(index=CDataProduct.COL_MAXPUR1))
            #dataRow.append(str)
            
            # stock
            #str = '%g' %obj.getFieldVal(index=CDataProduct.COL_ONHAND1)
            #dataRow.append(str)
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_ONHAND1))
            
            unit2 = obj.getFieldVal(index=CDataProduct.COL_UNIT2)
            if (unit2 is not None and unit2 != ''):
                str = '%g%s' %(obj.getFieldVal(index=CDataProduct.COL_ONHAND2), unit2)
            else:
                str = ''
            #dataRow.append(str)
            
            unit3 = obj.getFieldVal(index=CDataProduct.COL_UNIT3)
            if (unit3 is not None and unit3 != ''):
                str = '%g%s' %(obj.getFieldVal(index=CDataProduct.COL_ONHAND3), unit3)
            else:
                str = ''
            #dataRow.append(str)
            
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_POSITION))
            
            dataRow.append(obj.getFieldVal(index=CDataProduct.COL_MEMO))
            
            dataList.append(dataRow)
            
        return dataList

    def reloadItem(self, item):
        '''子类通过覆盖实现该函数实现条目刷新'''
        return CDataProduct.get_pro_list("product.id=" + self.GetItemText(item))[0]

    def getPeerId(self):
        '''用于支持 在订单中右键添加商品时，商品列表中，显示客户记录'''
        #return self.GetParent().GetParent().getPeerId() if hasattr(self.GetParent().GetParent(), "getPeerId") else None
        return kit.getRootWin(self).getPeerId() if hasattr(kit.getRootWin(self), "getPeerId") else None

class MyListCtrlProductPurchase(MyProductListCtrl):
    ''' 产品的采购分析 '''
    
    include_menu = True

    def makeCols(self): 
        self.only_warning = True
        self.showUnused = False
        self.only_less30 = False
    
        self.iId = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPosition = self.appendCol((u'仓位', wx.LIST_FORMAT_RIGHT, 50))
        self.iName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 200))
        #self.iCategory = self.appendCol((u'类型', wx.LIST_FORMAT_LEFT, -1))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 200))
        #self.iOnuse = self.appendCol((u'启用', wx.LIST_FORMAT_LEFT, 50))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 30))
        self.iPrice = self.appendCol((u'售价', wx.LIST_FORMAT_RIGHT, 0))        
        self.iCost = self.appendCol((u'预设成本', wx.LIST_FORMAT_RIGHT, 0))        
        self.iWarnStock = self.appendCol((u'预警线', wx.LIST_FORMAT_RIGHT, 60))
        self.iJinBo = self.appendCol((u'金博仓', wx.LIST_FORMAT_RIGHT, 60))
        self.i30Sale = self.appendCol((u'30天销量', wx.LIST_FORMAT_RIGHT, -1))
        self.i90Sale = self.appendCol((u'90天', wx.LIST_FORMAT_RIGHT, 60))
        self.i180Sale = self.appendCol((u'180天', wx.LIST_FORMAT_RIGHT, 60))
        self.i360Sale = self.appendCol((u'360天', wx.LIST_FORMAT_RIGHT, 60))
        self.iTotal = self.appendCol((u'库存价值', wx.LIST_FORMAT_RIGHT, -1))
        self.iLastPurPrice = self.appendCol((u'最近进价', wx.LIST_FORMAT_RIGHT, 0))
        self.iStock = self.appendCol((u'总库存', wx.LIST_FORMAT_RIGHT, 60))
        self.iMemo = self.appendCol((u'商品备注', wx.LIST_FORMAT_LEFT, 100))
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iStock).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            elif float(self.GetItem(index, self.iStock).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)
                
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iStock, self.i30Sale, self.iTotal])
        self.tStatList[self.iName].SetLabel(u'共%d条记录'  %self.GetItemCount())
    
    def getProSaleInfo(self, item=-1):
        if (item == -1):
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return []
            
        proId = int(self.GetItem(item, self.iId).GetText())
        proName = self.GetItem(item, self.iName).GetText()
        proSpec = self.GetItem(item, self.iSpec).GetText()
        unit = self.GetItem(item, self.iUnit).GetText()
        price = float(self.GetItem(item, self.iLastPurPrice).GetText())
            
        return [proId, proName,proSpec, unit, price]
        
    def setOnlyWarn(self, only_warning):
        self.only_warning = only_warning
        self.only_less30 = False

    def setOnlyLess30(self, only_less30):
        self.only_less30 = only_less30
        self.only_warning = False
        
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'keyword':, 'category':}
        '''
        dataList = []
        if (len(filter) == 0):
            filterSql = self.filterSql
        else:
            log(ERR, 'Undo')
            
        if (len(filterSql) == 0): 
            filterSql = '1=1'
        
        if not self.showUnused:
            filterSql += " and onUse=1"
            
        if self.only_warning:
            # filterSql += " and quantity<=lowest_qty and lowest_qty>0 and id not in (select proId from purchase_plan) "
            filterSql += " and quantity<=lowest_qty and lowest_qty>0 "

        if self.only_less30:
            # filterSql += " and quantity<s30_sale and id not in (select proId from purchase_plan) "
            filterSql += " and quantity<s30_sale "

        dataList = CDataProduct.get_purchase_report(filterSql)
        # for row in dataList:
            # print row 
            # row[self.iStock] = "%g" %row[self.iStock]
            # row[self.iWarnStock] = "%g" %row[self.iWarnStock]
            # row[self.iCost] = "%g" %row[self.iCost]
            # row[self.iPrice] = "%g" %row[self.iPrice]
            # row[self.iTotal] = "%g" %row[self.iTotal]
            # row[self.i30Sale] = "%g" %row[self.i30Sale]
            # row[self.i90Sale] = "%g" %row[self.i90Sale]
            # row[self.i180Sale] = "%g" %row[self.i180Sale]
            # row[self.i360Sale] = "%g" %row[self.i360Sale]
            # print row
        return dataList
        

class MyListCtrlProductProfitMall(MyProductListCtrl):
    '''商城产品利润报表'''
    
    def makeCols(self):        
        self.iId = self.appendCol((u'ID', wx.LIST_FORMAT_LEFT, 0))
        self.iDate = self.appendCol((u'日期', wx.LIST_FORMAT_LEFT, 90))
        self.iName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 130))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 130))
        self.iNum = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 50))
        self.iAmount = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, 60))
        self.iKickback = self.appendCol((u'总抽佣', wx.LIST_FORMAT_RIGHT, 60))
        self.iProfit = self.appendCol((u'总利润', wx.LIST_FORMAT_RIGHT, 60))
        self.iAvgPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 60))
        self.iAvgKickback = self.appendCol((u'抽佣', wx.LIST_FORMAT_RIGHT, 60))
        self.iLastCost = self.appendCol((u'入库价', wx.LIST_FORMAT_RIGHT, 60))        
        self.iUnitProfit = self.appendCol((u'利润', wx.LIST_FORMAT_RIGHT, 60))
        self.iPercent = self.appendCol((u'利润率', wx.LIST_FORMAT_RIGHT, 60))
        self.iQty = self.appendCol((u'库存', wx.LIST_FORMAT_RIGHT, 60))
        self.iWarnStock = self.appendCol((u'预警线', wx.LIST_FORMAT_RIGHT, 0))
        self.iMall = self.appendCol((u'商城', wx.LIST_FORMAT_LEFT, 60))
        self.iCustomer = self.appendCol((u'客户', wx.LIST_FORMAT_LEFT, 120))
        
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum, self.iAmount,self.iProfit])
        
        self.tStatList[self.iName].SetLabel(u'count:%d '%self.GetItemCount())
        
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iQty).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            elif float(self.GetItem(index, self.iQty).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)

    def convert(self, filter={}):

        filterSql = self.filterSql

        if (len(filterSql) == 0): 
            filterSql = '1=1'

        if (filter.has_key('dateStart')):
            filterSql += " AND billDate >= '%s' AND billDate <='%s' " %(filter['dateStart'], filter['dateEnd'])

        #if (filter.has_key('delivery_plan')):
        #    filterSql += " AND deliveryPlan='%s' " %(filter['delivery_plan'])

        #if (filter.has_key('peerId')):
        #    filterSql += " AND saledetails.peerId='%s' " %(filter['peerId'])
        if(filter['mall_40'] and not filter['mall_41']):
            filterSql += " AND r.Id=40 "
        elif (not filter['mall_40'] and filter['mall_41']):
            filterSql += " AND r.Id=41 "
        else:
            filterSql += " AND (r.Id=41 OR r.Id=40) "

        return CDataProduct.getProfitProOnMall(filterSql)

    # 子类通过覆写makeMenu编辑自定义菜单
    # include_menu = True
    # def makeMenu(self):
    #     MySortListCtrl.appendCommonMenu(self)


class MyListCtrlProductProfitReport(MyProductListCtrl):
    ''' 产品利润报表 '''
    
    def makeCols(self):
        self.iId = self.appendCol((u'ID', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 130))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 130))
        self.iNum = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 80))
        self.iAmount = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, 90))
        self.iAvgPrice = self.appendCol((u'平均单价', wx.LIST_FORMAT_RIGHT, 80))
        self.iLastCost = self.appendCol((u'入库价', wx.LIST_FORMAT_RIGHT, 80))
        self.iUnitProfit = self.appendCol((u'单位利润', wx.LIST_FORMAT_RIGHT, 80))
        self.iProfit = self.appendCol((u'总利润', wx.LIST_FORMAT_RIGHT, 90))
        self.iPercent = self.appendCol((u'利润率', wx.LIST_FORMAT_RIGHT, 90))
        self.iQty = self.appendCol((u'当前库存', wx.LIST_FORMAT_RIGHT, 90))
        self.iWarnStock = self.appendCol((u'预警线', wx.LIST_FORMAT_RIGHT, 0))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum, self.iAmount,self.iProfit])
        
        self.tStatList[self.iName].SetLabel(u'count:%d '%self.GetItemCount())
        
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iQty).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            elif float(self.GetItem(index, self.iQty).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)

    def convert(self, filter={}):

        filterSql = self.filterSql

        if (len(filterSql) == 0): 
            filterSql = '1=1'

        if (filter.has_key('dateStart')):
            filterSql += " AND billDate >= '%s' AND billDate <='%s' " %(filter['dateStart'], filter['dateEnd'])

        if (filter.has_key('delivery_plan')):
            filterSql += " AND deliveryPlan='%s' " %(filter['delivery_plan'])

        if (filter.has_key('peerId')):
            filterSql += " AND saledetails.peerId='%s' " %(filter['peerId'])

        return CDataProduct.getProfitPro(filterSql)

    # 子类通过覆写makeMenu编辑自定义菜单
    # include_menu = True
    # def makeMenu(self):
    #     MySortListCtrl.appendCommonMenu(self)


class MyListCtrlProductRegionSale(MyProductListCtrl):
    ''' 产品的地区销售 '''
    
    include_menu = True

    def makeCols(self): 
        self.iId = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPosition = self.appendCol((u'仓位', wx.LIST_FORMAT_RIGHT, 50))
        self.iName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 130))
        #self.iCategory = self.appendCol((u'类型', wx.LIST_FORMAT_LEFT, -1))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 130))
        #self.iOnuse = self.appendCol((u'启用', wx.LIST_FORMAT_LEFT, 50))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 40))
        self.i30Sale = self.appendCol((u'总销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iStock = self.appendCol((u'库存', wx.LIST_FORMAT_RIGHT, -1))
        self.iPrice = self.appendCol((u'预设售价', wx.LIST_FORMAT_RIGHT, -1))        
        self.iCost = self.appendCol((u'预设成本', wx.LIST_FORMAT_RIGHT, -1))       
        #self.iLastPurPrice = self.appendCol((u'最近进价', wx.LIST_FORMAT_RIGHT, 0))
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iStock).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            else:
                self.resetBgcolour(index)

    def setRegion(self, regionId):
        self.m_regionId = regionId

    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'keyword':, 'category':}
        '''

        if (len(filter) == 0):
            filterSql = self.filterSql
        else:
            log(ERR, 'Undo')

        if (len(filterSql) == 0): 
            filterSql = '1=1'
        
        filterSql += " and customer.region=%d " %self.m_regionId
        filterSql += " and billId > 'XS-" + (datetime.date.today() - datetime.timedelta(days=365)).strftime("%Y-%m-%d") + "-00001' "

        dataList = CDataProduct.get_region_sales(filterSql)
        return dataList


class MyListCtrlProfit(MySortListCtrl):
    '''核算订单利润，未启用'''
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)
        
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum,self.iProfit])

        self.tStatList[self.iProId].SetLabel(u'共%d条记录'  %self.GetItemCount())
        
    def makeCols(self):
        self.iProId = self.appendCol((u'商品编号', wx.LIST_FORMAT_LEFT, 0))
        self.iProName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 120))
        self.iProSpec = self.appendCol((u'商品规格',  wx.LIST_FORMAT_LEFT, 120))
        self.iUnit = self.appendCol((u'单位',  wx.LIST_FORMAT_LEFT, 40))
        self.iNum = self.appendCol((u'数量',  wx.LIST_FORMAT_RIGHT, 60))
        self.iPrice = self.appendCol((u'单价',  wx.LIST_FORMAT_RIGHT, 60))
        #self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, -1))
        #self.iMemo = self.appendCol((u'备注',  wx.LIST_FORMAT_LEFT, 100))
        self.iCost = self.appendCol((u'应用成本',  wx.LIST_FORMAT_RIGHT, -1))
        self.iUnitProfit = self.appendCol((u'单位利润',  wx.LIST_FORMAT_RIGHT, -1))
        self.iProfit = self.appendCol((u'预期利润',  wx.LIST_FORMAT_RIGHT, -1))
        self.iPercent = self.appendCol((u'利润率', wx.LIST_FORMAT_RIGHT, 80))
                       
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'billId':XX, 'cost':'avg','pur','base'}
        '''
        data = []
        
        filterSql = "billId='%s'"  %filter['billId']
        
        objList = CDataSaleDetail.fetch(filterSql)
        if (objList is None):
            return data

        for saleDetail in (objList):
            dataRow = []
            proId = saleDetail.getFieldVal('proId')
            proObj = CDataProduct.getInstance({'id':proId})
            dataRow.append(proId)
            dataRow.append(saleDetail.getFieldVal('proName'))
            dataRow.append(proObj.getFieldVal('spec'))#spec
            dataRow.append(saleDetail.getFieldVal('unit'))
            dataRow.append(saleDetail.getFieldVal('num'))
            dataRow.append(saleDetail.getFieldVal('price'))
            #dataRow.append(saleDetail.getFieldVal('total'))
            #dataRow.append(saleDetail.getValue(saleDetail.COL_MEMO))
            
            if (filter['cost']=='last_cost'):
                #cost = proObj.getPricePur(saleDetail.getFieldVal('unit'))
                cost = proObj.getFieldVal('last_cost')
                dataRow.append(cost)
            else:
                assert filter['cost']=='last_cost'
            
            unitProfit = saleDetail.getFieldVal('price') - (cost or 0)
            dataRow.append(unitProfit)
            
            profit = unitProfit*saleDetail.getFieldVal('num')
            dataRow.append(profit)
            dataRow.append(round(unitProfit/saleDetail.getFieldVal('price'),2) if saleDetail.getFieldVal('price') > 0 else 0)

            data.append(dataRow)
             
        return data

    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())
        
class MyOrderContentListCtrl(MySortListCtrl):
    
    '''显示订单内容'''
    
    
##    def __init__(self, parent):
##                
##        MySortListCtrl.__init__(self, parent=parent,
##                        style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)

        
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum,self.iTotal])

        self.tStatList[self.iProName].SetLabel(u'共%d条记录'  %self.GetItemCount())
        
            
    def makeCols(self):
        self.iProId = self.appendCol((u'商品编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPosition = self.appendCol((u'仓位',  wx.LIST_FORMAT_LEFT, 50))
        self.iProName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 200))
        self.iProSpec = self.appendCol((u'商品规格',  wx.LIST_FORMAT_LEFT, 200))
        self.iUnit = self.appendCol((u'单位',  wx.LIST_FORMAT_LEFT, 40))
        self.iNum = self.appendCol((u'数量',  wx.LIST_FORMAT_RIGHT, 60))
        self.iPrice = self.appendCol((u'单价',  wx.LIST_FORMAT_RIGHT, 60))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, 70))
        self.iMemo = self.appendCol((u'备注',  wx.LIST_FORMAT_LEFT, 200))
        self.iQty = self.appendCol((u'库存',  wx.LIST_FORMAT_LEFT, 0))
        self.iPeerId = self.appendCol((u'客户ID',  wx.LIST_FORMAT_LEFT, 0))
        self.iWarnStock = self.appendCol((u'预警线', wx.LIST_FORMAT_RIGHT, 0))
                       
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'billId':}
        '''
        return CDataSaleDetail.getContent(filter['billId'])
        #data = []
        
        # filterSql = "billId='%s'"  %filter['billId']
        
        # objList = CDataSaleDetail.fetch(filterSql)
        # if (objList is None):
        #     return data

        # for saleDetail in (objList):
        #     dataRow = []
        #     proId = saleDetail.getFieldVal('proId')
        #     proObj = CDataProduct.getInstance({'id':proId})
        #     dataRow.append(proId)
        #     #dataRow.append(proObj.getFieldVal('position'))
        #     dataRow.append(saleDetail.getFieldVal('from_position'))
        #     dataRow.append(saleDetail.getFieldVal('proName'))
        #     dataRow.append(proObj.getFieldVal('spec'))#spec
        #     dataRow.append(saleDetail.getFieldVal('unit'))
        #     dataRow.append(saleDetail.getFieldVal('num'))
        #     dataRow.append(saleDetail.getFieldVal('price'))
        #     dataRow.append(saleDetail.getFieldVal('total'))
        #     dataRow.append(saleDetail.getValue(saleDetail.COL_MEMO))
        #     dataRow.append(proObj.getFieldVal('onhand1'))
        #     dataRow.append(saleDetail.getFieldVal('peerId'))

        #     data.append(dataRow)

        #return data

    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())
    
    def getPeerId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iPeerId).GetText())
        
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iQty).GetText()) < 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 负库存，红色
            elif float(self.GetItem(index, self.iQty).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)
                
                
class MyListCtrlOrderVoucherList(MySortListCtrl):
    '''显示订单关联的付款单明细'''
    include_menu=True
    def makeCols(self):
        self.iVoucherId = self.appendCol((u'付款单号', wx.LIST_FORMAT_LEFT, 180))
        self.iAccount = self.appendCol((u'账户名称', wx.LIST_FORMAT_LEFT, -1))
        self.iMoney = self.appendCol((u'付款总金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iAlloct = self.appendCol((u'分配金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iMemo = self.appendCol((u'备注',  wx.LIST_FORMAT_LEFT, 200))
        self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT,  -1))
        self.iRecorder = self.appendCol((u'操作员', wx.LIST_FORMAT_LEFT, -1))
                    
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'billId':}
        '''
        data = []
        
        #filterSql = "billId='%s'"  %filter['billId']
        list = self.clsFund.getPaidList(filter['billId'])
        for voucherId,allcot in list:
            dataRow = []
            voucherObj = self.clsVoucher.findObj(voucherId)
            if voucherObj is None:
                #print('error voucherId', voucherId, money, filter['billId'])
                continue
            
            dataRow.append(voucherId)
            dataRow.append(voucherObj.getAccountName())
            dataRow.append(voucherObj.getValue(voucherObj.iMoney))
            dataRow.append(str(allcot))
            dataRow.append(voucherObj.getValue(voucherObj.iMemo))
            dataRow.append(CDataStaff.getName(voucherObj.getValue(voucherObj.iHandlerId)))
            dataRow.append(CDataStaff.getName(voucherObj.getValue(voucherObj.iRecorderId)))
            
            data.append(dataRow)
            
        return data
    
    def setOrderStyle(self, clsPeer):
        if clsPeer == CDataCustomer:
            self.clsVoucher = CDataVoucher
            self.clsFund = CRelFundCustomer
        elif clsPeer == CDataSupplier:
            self.clsVoucher = CDataVoucherSupplier
            self.clsFund = CRelFundSupplier    
    
    def makeMenu(self):
        item = self.menu.Append(-1, u'查看订单分配情况')
        self.Bind(wx.EVT_MENU, self.OnMenuCheck, item) 
        
    def OnMenuCheck(self, event):
        event.Skip()
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        voucherId = self.GetItem(item, self.iVoucherId).GetText()
        
##        dlg = PopupTWinList.PopupTWinList(self, MyListCtrlOrderAmountAllocted)
##        dlg.lc.refresh({'voucherId':voucherId, 'show':'alloct'})
##        dlg.Popup()
        dlg = wx.PopupTransientWindow(self)
        dlg.SetSize(wx.Size(550,100))
        dlg.Position(wx.GetMousePosition(), (0,0)) # 会导致PopupMenu时PyAssertionError
        dlg.Popup()
        
        lc = MyListCtrlOrderAmountAllocted(dlg, CDataCustomer)
        lc.SetSize(wx.Size(550,100))
        lc.SetBackgroundColour("#FFB6C1")
        lc.refresh({'voucherId':voucherId, 'show':'alloct'})        
              
class MyListCtrlPurContent(MySortListCtrl):
    
    '''显示订单内容'''
    
    
##    def __init__(self, parent):
##                
##        MySortListCtrl.__init__(self, parent=parent,
##                        style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum,self.iTotal,self.iChargeTotal,self.iWeightTotal])

        self.tStatList[self.iProName].SetLabel(u'共%d条记录'  %self.GetItemCount())
        
    def makeCols(self):
        self.iProId = self.appendCol((u'商品编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPosition = self.appendCol((u'仓位', wx.LIST_FORMAT_LEFT, 50))
        self.iProName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 140))
        self.iProSpec = self.appendCol((u'商品规格',  wx.LIST_FORMAT_LEFT, 140))
        self.iUnit = self.appendCol((u'单位',  wx.LIST_FORMAT_LEFT, 40))
        self.iNum = self.appendCol((u'数量',  wx.LIST_FORMAT_RIGHT, 60))
        self.iPrice = self.appendCol((u'单价',  wx.LIST_FORMAT_RIGHT, 70))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, 70))
        self.iMemo = self.appendCol((u'备注',  wx.LIST_FORMAT_LEFT, 150))
        self.iCharge = self.appendCol((u'运费',  wx.LIST_FORMAT_LEFT, 60))
        self.iChargeTotal = self.appendCol((u'总运费',  wx.LIST_FORMAT_LEFT, 70))
        self.iWeight = self.appendCol((u'重量',  wx.LIST_FORMAT_LEFT, 60))
        self.iWeightTotal = self.appendCol((u'总重量',  wx.LIST_FORMAT_LEFT, 70))
        self.iQty = self.appendCol((u'库存',  wx.LIST_FORMAT_LEFT, 0))
        #self.iPeerId = self.appendCol((u'客户ID',  wx.LIST_FORMAT_LEFT, 0))
        self.iWarnStock = self.appendCol((u'预警线', wx.LIST_FORMAT_RIGHT, 0))
           
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'billId':}
        '''

        return CDataPurDetail.getContent(filter['billId'])
        data = []
        
        filterSql = "billId='%s'"  %filter['billId']
        
        objList = CDataPurDetail.fetch(filterSql)
        if (objList is None):
            return data

        for obj in (objList):
            dataRow = []
            proId = obj.getValue(obj.COL_PROID)
            proObj = CDataProduct.getInstance({'id':proId})
            #proName = proObj.getValue(proObj.COL_NAME)
            proName = obj.getValue(obj.COL_PRONAME)
            proSpec = proObj.getValue(proObj.COL_SPEC)
            proMemo = proObj.getValue(proObj.COL_MEMO)
            
            dataRow.append(proId)
            dataRow.append(proObj.getValue(proObj.COL_POSITION))
            dataRow.append(proName)
            dataRow.append(proSpec)#spec
            dataRow.append(obj.getValue(obj.COL_UNIT))
            dataRow.append(obj.getValue(obj.COL_NUM))
            dataRow.append(obj.getValue(obj.COL_PRICE))
            dataRow.append(obj.getValue(obj.COL_TOTAL))
            dataRow.append(obj.getValue(obj.COL_MEMO))
            dataRow.append(obj.getValue(obj.COL_CHARGE))# if obj.getValue(obj.COL_CHARGE) > 0  else proObj.getValue(proObj.COL_FREIGHT))
            dataRow.append(obj.getValue(obj.COL_CHARGE) * obj.getValue(obj.COL_NUM))
            dataRow.append(proObj.getValue(proObj.COL_WEIGHT))
            dataRow.append(proObj.getValue(proObj.COL_WEIGHT) * obj.getValue(obj.COL_NUM))

            data.append(dataRow)
             
        return data

    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)
        self.menu.AppendSeparator()
        MySortListCtrl.appendMenuModifyQty(self)
        
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())

    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iQty).GetText()) < 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 负库存，红色
            elif float(self.GetItem(index, self.iQty).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)
    
class MyListCtrlDelivery(MySortListCtrl):
    include_menu = True
    
    def makeCols(self):
        #self.iID = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, -1))
        self.iAddr = self.appendCol((u'配送方式', wx.LIST_FORMAT_LEFT, 300))
        #self.iMemo = self.appendCol((u'备注说明', wx.LIST_FORMAT_LEFT, 200))
    
    def makeMenu(self):
        item = self.menu.Append(-1, u'显示所有配送方式')
        self.Bind(wx.EVT_MENU, self.OnShowAll, item) 
    
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
    
    def getDlvyId(self, item):
        #return int(self.GetItem(item, self.iID).GetText())
        return self.GetItem(item, self.iAddr).GetText()
        
    def OnShowAll(self, event):
        self.refresh()
        
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx,}
        '''
        data = []
        if (filter.has_key('peerId')):
            data = CRelCustDlvy.getDlvy(filter['peerId']) 
        else:
            dlvyObjList = CDataDelivery.getObjList()        
        
            for obj in dlvyObjList:
                dataRow = []
                #dataRow.append(obj.getValue(obj.COL_ID))
                dataRow.append(obj.getValue(obj.COL_NAME))
                #dataRow.append(obj.getValue(obj.COL_MEMO))
                
                data.append(dataRow)
        
        return data
      
class MyCustomerListCtrl(MySortListCtrl):
    '''显示customer列表，以供选择'''  
##    def __init__(self, parent):
##        self.cols = [(u'编号', wx.LIST_FORMAT_LEFT, 0),
##                    (u'客户名称', wx.LIST_FORMAT_LEFT, 200),
##                    (u'客户类型', wx.LIST_FORMAT_LEFT, -1),
##                    (u'客户地区', wx.LIST_FORMAT_LEFT, -1),
##                    (u'近期销售', wx.LIST_FORMAT_LEFT, 130),
##                    (u'联系人', wx.LIST_FORMAT_LEFT, 0),
##                    (u'联系电话', wx.LIST_FORMAT_LEFT, 110),
##                    (u'期初欠款', wx.LIST_FORMAT_LEFT, 0),
##                    (u'欠款总额', wx.LIST_FORMAT_LEFT, 100),#2014-08-01
##                    (u'联系地址', wx.LIST_FORMAT_LEFT, 0),
##                    (u'电子邮件', wx.LIST_FORMAT_LEFT, 0),
##                    (u'传真', wx.LIST_FORMAT_LEFT,  0),
##                    (u'备注', wx.LIST_FORMAT_LEFT, 200)]
##            
##        MySortListCtrl.__init__(self, parent=parent,
##                        style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
##    
##        # debt改为初始化时计算，所以不会产生效率问题
##        self.showDebt = True
    
    def makeCols(self):
        self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 200))
        self.iPrintName = self.appendCol((u'打印名称', wx.LIST_FORMAT_LEFT, 0))
        self.iType = self.appendCol((u'类型', wx.LIST_FORMAT_LEFT, 50))
        self.appendCol((u'地区', wx.LIST_FORMAT_LEFT, 50))
        self.appendCol((u'近期销售', wx.LIST_FORMAT_LEFT, 110))
        self.appendCol((u'联系人', wx.LIST_FORMAT_LEFT, 0))
        self.iPhone = self.appendCol((u'联系电话1', wx.LIST_FORMAT_LEFT, 105))
        self.iPhone2 = self.appendCol((u'联系电话2', wx.LIST_FORMAT_LEFT, 60))
        self.iPhone3 = self.appendCol((u'联系电话3', wx.LIST_FORMAT_LEFT, 00))
        self.appendCol((u'销量等级', wx.LIST_FORMAT_LEFT, 25))
        self.appendCol((u'微信', wx.LIST_FORMAT_LEFT, 45))
        self.iInitDebt = self.appendCol((u'期初欠款', wx.LIST_FORMAT_RIGHT, 0))
        self.iDebt = self.appendCol((u'总欠款', wx.LIST_FORMAT_RIGHT, 70))        
        #self.appendCol((u'联系地址', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'电子邮件', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'传真', wx.LIST_FORMAT_LEFT,  0))
        self.iLog = self.appendCol((u'最近联系', wx.LIST_FORMAT_LEFT, 150))
        self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 150))
        self.iDebtUnsend = self.appendCol((u'未送单', wx.LIST_FORMAT_LEFT, 60))
        self.iDebtSend = self.appendCol((u'已送单', wx.LIST_FORMAT_LEFT, 60))
        self.appendCol((u'绑定司机', wx.LIST_FORMAT_LEFT, 150))
        self.iOverdue = self.appendCol((u'超期', wx.LIST_FORMAT_LEFT, 0))
        self.m_only_show_wujin = False
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iDebt,self.iDebtUnsend,self.iDebtSend])

        self.tStatList[self.iPeerName].SetLabel(u'共%d条记录'  %self.GetItemCount())
    
    include_menu = True
    def makeMenu(self):
        
        item = self.menu.Append(-1, u'拷贝客户名称')
        self.Bind(wx.EVT_MENU, self.OnMenuCopyName, item)
        
        self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'添加客情')
        self.Bind(wx.EVT_MENU, self.OnMenuAddLog, item)

        item = self.menu.Append(-1, u'新增销售单')
        self.Bind(wx.EVT_MENU, self.OnMenuNewOrder, item)
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'查看客情')
        self.Bind(wx.EVT_MENU, self.OnMenuShowLog, item)
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'查看图片')
        self.Bind(wx.EVT_MENU, self.OnMenuShowImage, item)

        self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'编辑客户')
        self.Bind(wx.EVT_MENU, self.OnMenuEditCustmor, item) 

        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'查看地区销量(一年)')
        self.Bind(wx.EVT_MENU, self.OnMenuRegionSale, item)

        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
      
    
    def OnMenuCopyName(self, event):
        ''' 拷贝客户名称 '''
        
        import pyperclip
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if item >= 0:
            pyperclip.copy(self.GetItem(item, self.iPeerName).GetText())

    def OnMenuAddLog(self, event):
        ''' 添加客情 '''
        import DlgAddCustomerLog
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        dlg = DlgAddCustomerLog.create(self)
        dlg.setData(self.getPeerId(item))
        dlg.ShowModal()
        
        peerObj = CDataCustomer.getData({'id':self.getPeerId(item)})
        self.SetStringItem(item, self.iLog, peerObj.getValue(peerObj.COL_LMMEMO))  
    
    def OnMenuShowLog(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        peerObj = CDataCustomer.getData({"id":self.getPeerId(item)})
        kit.getRootWin(self).showCustLog(peerObj)

    def OnMenuRegionSale(self, event):
        

        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        peerObj = CDataCustomer.getData({"id":self.getPeerId(item)})
        self.getMainFrame().showRegionSale(peerObj.getValue(peerObj.COL_REGION))

    def getMainFrame(self):
        #return self.GetParent().GetParent()
        win = self
        while(win.GetParent()):
            win = win.GetParent()
        return win

    def getPeerId(self, item):
        return int(self.GetItem(item, 0).GetText())
        
    def setViewPeerAll(self):
        #self.iDebt = 9
        #self.iInitDebt = 8
        self.SetColumnWidth(self.iInitDebt, 0)# 不显示
        self.SetColumnWidth(self.iDebt, 100)
        self.SetColumnWidth(self.iDebtSend, 100)
        self.SetColumnWidth(self.iPhone, 0)

        self.SetColumnWidth(self.iPhone2, 0)
        self.SetColumnWidth(self.iType, 0)
    
        #self.showDebt = True
    
    def set_only_wujin(self, only_wujin):
        self.m_only_show_wujin = only_wujin
    
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'all':,}
        '''
        return CDataCustomer.getCustomerList(
            sqlLike = CDataCustomer.getSearchSql(filter['all'], "c.") if (filter.has_key('all')) else ""
            ,regionId = filter['regionId'] if (filter.has_key('regionId')) else None
            ,only_wujindian = self.m_only_show_wujin or (filter['only_wujindian'] if (filter.has_key('only_wujindian')) else False)
            ,only_alarm_customer = filter['only_alarm_customer'] if (filter.has_key('only_alarm_customer')) else None
            ,only_send_debt = None
        )
#         data = []
#         sql = ''
#         if (filter.has_key('all')): 
# ##            str = "'%%%s%%'"  %filter['all']
# ##            for field in CDataCustomer.m_fieldNames:
# ##                sql += '%s like %s or ' %(field, str)
# ##            sql = sql[:-4]
#             sql = CDataCustomer.getSearchSql(filter['all'])
#         elif (filter.has_key('regionId')):
#             sql = " region=%d " %(filter['regionId'])
#             if (filter.has_key('only_wujindian') and filter["only_wujindian"]):
#                 sql += " and type=4 "

#         if (filter.has_key('only_alarm_customer') and filter["only_alarm_customer"]):
#             sql = "("+sql+")"+""" and ((lvl_sales='A' AND DATEDIFF(CURDATE(),lastOrder)>30) 
#                 or (lvl_sales='B' AND DATEDIFF(CURDATE(),lastOrder)>60) 
#                 or (lvl_sales='C' AND DATEDIFF(CURDATE(),lastOrder)>90)) """
            
#         print sql
        
#         objList = CDataCustomer.fetch(sql)
#         if (objList is None):
#             return data

#         today = datetime.datetime.today().date()
        
#         for customer in (objList):
#             dataRow = []
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_ID))            
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_NAME))
            
#             dataRow.append(customer.getType())#getFieldVal(index=CDataCustomer.COL_TYPE))
#             if (self.m_only_show_wujin and customer.getFieldVal(index=CDataCustomer.COL_TYPE) != 4):
#                 continue
                
#             dataRow.append(customer.getRegion())
            
#             # lastOrder
#             date = customer.getValue(CDataCustomer.COL_LASTORDER)
#             if date is not None:
#                 span = today - date
#                 #lastDate = u'%d天前(%d-%d-%d)' %(span.days, date.year, date.month, date.day)
#                 lastDate = u'%s(%d天前)' %(date, span.days)
#                 dataRow.append(lastDate)
#             else:
#                 dataRow.append(u'') # 空串也要加u，否则比较会出错
            
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_LINKMAN))#spec
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_LMPHONE))
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_EMAIL))
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_LVL_SALES) or '~')
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_WECHAT))
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_DEBT))
#             #2014-08-01
#             # 会导致1-2s的延迟
#             dataRow.append(customer.getDebt())
#             #if (self.showDebt):
#             #    dataRow.append(customer.getDebt())
#             #else:
#             #    dataRow.append(u'停用')
                
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_ADDR))
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_EMAIL))
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_FAX))#pro memo
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_LMMEMO))
#             dataRow.append(customer.getFieldVal(index=CDataCustomer.COL_MEMO))
#             #dataRow.append(CDataStaff.getName(customer.getFieldVal(index=CDataCustomer.COL_PIONEER)))
#             create_date = customer.getValue(CDataCustomer.COL_CREATE_TIME)
#             if create_date is not None:
#                 dataRow.append(CDataStaff.getName(customer.getFieldVal(index=CDataCustomer.COL_PIONEER))+create_date.strftime("%y%m%d"))
#             else:
#                 dataRow.append(CDataStaff.getName(customer.getFieldVal(index=CDataCustomer.COL_PIONEER)))
            
#             dataRow.append("1" if customer.IsOverdue() else "0")

#             data.append(dataRow)
             
#         return data

    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if self.GetItem(index, self.iOverdue).GetText() == '1':
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index) 


class MyCustomerStatListCtrl(MyCustomerListCtrl):
    
    include_statBar = False#True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            self.setStatSum([self.iDebt, self.iEval, self.iSales])
            self.tStatList[self.iPeerName].SetLabel(u'共%d条记录'  %self.GetItemCount())

    def makeCols(self):
        self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 200))
        #self.appendCol((u'类型', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'地区', wx.LIST_FORMAT_LEFT, 0))
        self.appendCol((u'近期销售', wx.LIST_FORMAT_LEFT, 130))
        #self.appendCol((u'联系人', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'联系电话', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'联系电话', wx.LIST_FORMAT_LEFT, 0))
        self.iDebt = self.appendCol((u'总欠款', wx.LIST_FORMAT_RIGHT, 70))
        self.appendCol((u'微信', wx.LIST_FORMAT_LEFT, 45))
        self.appendCol((u'销量等级', wx.LIST_FORMAT_LEFT, 25))
        self.iEval = self.appendCol((u'评估销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iSales = self.appendCol((u'我司销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iSOM = self.appendCol((u'份额', wx.LIST_FORMAT_RIGHT, 50))        
        #self.iInitDebt = self.appendCol((u'期初欠款', wx.LIST_FORMAT_RIGHT, 0))        
        #self.appendCol((u'联系地址', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'电子邮件', wx.LIST_FORMAT_LEFT, 0))
        #self.appendCol((u'传真', wx.LIST_FORMAT_LEFT,  0))
        self.iLog = self.appendCol((u'最近联系', wx.LIST_FORMAT_LEFT, 150))
        self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 150))        
        self.appendCol((u'绑定司机', wx.LIST_FORMAT_LEFT, 150))
        self.iOverdue = self.appendCol((u'超期', wx.LIST_FORMAT_LEFT, 0))

        self.m_only_show_wujin = False

    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'all':,}
        '''
        data = []
        sql = ''

        if (filter.has_key('regionId')):
            sql = " region=%d " %(filter['regionId'])

        if (filter.has_key('routeId')):
            sql = " region in (select regionId from delivery_route_region where routeId=%d) " %(filter['routeId'])
        
        if (filter.has_key('only_wujindian') and filter["only_wujindian"]):
            sql += " and type=4 "

        if (filter.has_key('only_alarm_customer') and filter["only_alarm_customer"]):
            sql = "("+sql+")"+""" and ((lvl_sales='A' AND DATEDIFF(CURDATE(),lastOrder)>30) 
                or (lvl_sales='B' AND DATEDIFF(CURDATE(),lastOrder)>60) 
                or (lvl_sales='C' AND DATEDIFF(CURDATE(),lastOrder)>90)) """

        return CDataCustomer.query_stat_som(sql)



class MyListCtrlOverdueCustomer(MySortListCtrl):
    ''' 超期客户列表 '''

    def makeCols(self):

        self.iId = self.appendCol((u'客户ID', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 200))
        self.iRegion = self.appendCol((u'地区', wx.LIST_FORMAT_LEFT, 50))
        self.iLastOrder = self.appendCol((u'近期销售', wx.LIST_FORMAT_LEFT, 150))
        self.iLog = self.appendCol((u'最近联系', wx.LIST_FORMAT_LEFT, 150))
        #self.iOverdueDays = self.appendCol((u'超期', wx.LIST_FORMAT_LEFT, 50))
        self.iLevel = self.appendCol((u'等级', wx.LIST_FORMAT_LEFT, 60))
        self.iDifficult = self.appendCol((u'难度', wx.LIST_FORMAT_LEFT, 50))
        self.iPhone = self.appendCol((u'联系电话', wx.LIST_FORMAT_LEFT, 100))
        self.iEmail = self.appendCol((u'电子邮件', wx.LIST_FORMAT_LEFT, 60))
        self.iWechat = self.appendCol((u'微信', wx.LIST_FORMAT_LEFT, 60))  
        self.iMemo = self.appendCol((u'客户备注', wx.LIST_FORMAT_LEFT, 150))
        self.iInterval = self.appendCol((u'间隔', wx.LIST_FORMAT_LEFT, 40))
        self.iRegionId = self.appendCol((u'地区ID', wx.LIST_FORMAT_LEFT, 0))
        self.iSalesman = self.appendCol((u'专员', wx.LIST_FORMAT_LEFT, 60))
        
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        
        self.tStatList[self.iPeerName].SetLabel(u'共%d条记录'  %self.GetItemCount())
    
    include_menu = True
    def makeMenu(self):
        
        item = self.menu.Append(-1, u'添加客情')
        self.Bind(wx.EVT_MENU, self.OnMenuAddLog, item) 
        
        self.menu.AppendSeparator()
                
        item = self.menu.Append(-1, u'查看图片')
        self.Bind(wx.EVT_MENU, self.OnMenuShowImage, item) 
        
        self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'编辑客户')
        self.Bind(wx.EVT_MENU, self.OnMenuEditCustmor, item) 
        
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
    

    def OnMenuAddLog(self, event):
        ''' 添加客情 '''
        import DlgAddCustomerLog
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        dlg = DlgAddCustomerLog.create(self)
        dlg.setData(self.getPeerId(item))
        dlg.ShowModal()
        
        peerObj = CDataCustomer.getData({'id':self.getPeerId(item)})
        self.SetStringItem(item, self.iLog, peerObj.getValue(peerObj.COL_LMMEMO))  

    def OnMenuShowImage(self, event):
        import DlgProductImage
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = DlgProductImage.create(self)
        dlg.SetCustomer(self.getPeerId(item))
        dlg.ShowModal()  
        
    def getPeerId(self, item):
        return int(self.GetItem(item, 0).GetText())

    
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'all':,}
        '''
        
        return CDataCustomer.query_overdue(
            regionId = filter['regionId'] if filter.has_key('regionId') else None,
            salesman = filter['salesman'] if filter.has_key('salesman') else None,
            show_all = filter['show_all'] if filter.has_key('show_all') else False,
            only_show_delivery = filter['only_show_delivery'] if filter.has_key('only_show_delivery') else False
            )


class MyListCtrlCustomerYearsSale(MySortListCtrl):
    '''客户的年销量'''  
    
    def makeCols(self):
        #self.cols =[]
    
        self.iYear = self.appendCol((u'年度', wx.LIST_FORMAT_LEFT, 60))
        self.iSale = self.appendCol((u'销量', wx.LIST_FORMAT_RIGHT, 80))
    
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iSale])

    def convert(self, filter={}):
        
        return CDataCustomer.query_year_sales(filter["customer_id"])

class MyListCtrlPeer(MySortListCtrl):
    '''显示peer列表，以供选择'''  
##    def __init__(self, parent):
##        
##        #self.setCols()
##        
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    def makeCols(self):
        #self.cols =[]
    
        self.iId = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'单位名称', wx.LIST_FORMAT_LEFT, 250))
        self.iCode = self.appendCol((u'拼音码', wx.LIST_FORMAT_LEFT, -1))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_RIGHT, 150))
    
    def getSelectObj(self):
        cls = CDataPeer
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return None
        id = int(self.GetItemText(item))
        return cls.getFirstInstance({cls.fi_id:id})
        
    def convert(self, filter={}):
        data = []
        
        for obj in CDataPeer.getObjList():
            dataRow = []
            dataRow.append(obj.getValue(obj.fi_id))
            dataRow.append(obj.getValue(obj.fi_name))
            dataRow.append(obj.getValue(obj.fi_briefCode))
            dataRow.append(obj.getValue(obj.fi_memo))

            data.append(dataRow)
             
        return data

class MyListCtrlPeerHistory(MySortListCtrl):
    '''显示peer列表，以供选择'''  
    
    include_statBar = True
    include_menu = True
  
    def makeCols(self):
        
        cols = [(u'编号', wx.LIST_FORMAT_LEFT, 0),
                (u'单位名称', wx.LIST_FORMAT_LEFT, 0),
                (u'日期', wx.LIST_FORMAT_LEFT, 100),
                (u'科目', wx.LIST_FORMAT_LEFT, 150),
                (u'规格', wx.LIST_FORMAT_LEFT, 150),
                (u'单位', wx.LIST_FORMAT_LEFT, 40),
                (u'数量', wx.LIST_FORMAT_RIGHT, 50),
                (u'单价', wx.LIST_FORMAT_RIGHT, 80),
                (u'小计', wx.LIST_FORMAT_RIGHT, 80),
                (u'备注', wx.LIST_FORMAT_LEFT, 200),
                (u'经手人', wx.LIST_FORMAT_LEFT, -1),
                (u'操作员', wx.LIST_FORMAT_LEFT, -1)]
                
        [self.iId, self.iName, self.iDate, self.iItem, self.iSpec,self.iUnit,self.iNum,self.iPrice,
        self.iTotal,self.iMemo,self.iHandler,self.iOperator] = self.appendColList(cols)
    
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal])
    
    def makeMenu(self):
        '''由子类重载该函数，以定制菜单。
            可以在子类中调用MySortListCtrl.appendCommonMenu以默认添加以下菜单'''
        item = self.menu.Append(-1, u'修改记录')
        self.Bind(wx.EVT_MENU, self.OnModify, item) 
        
        self.menu.AppendSeparator()
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'删除记录')
            self.Bind(wx.EVT_MENU, self.OnDelItem, item) 
        
            self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'编辑备注')
        self.Bind(wx.EVT_MENU, self.OnEditMemo, item) 
    
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
        
    def OnEditMemo(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        memo = self.GetItem(item, self.iMemo).GetText()
        dlg = wx.TextEntryDialog(
                self, u'修改订单备注：',u'修改订单备注：', memo)
        if dlg.ShowModal() == wx.ID_OK:        
            id = int(self.GetItem(item, self.iId).GetText())
            num = self.GetItem(item, self.iNum).GetText()
            if num == '':
                obj = CDataPeerFund.findObj(id)
            else:
                obj = CDataPeerLend.findObj(id)
            obj.setValue(obj.fi_memo, dlg.GetValue())
            obj.update()
            #self.refresh()
            
    def OnModify(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        num = self.GetItem(item, self.iNum).GetText()
        if num == '':
            self.modifyVoucher(item)
        else:
            self.modifyLend(item)

    def modifyVoucher(self, item):

        amount = self.GetItem(item, self.iTotal).GetText()
        dlg = wx.TextEntryDialog(
                self, u'修改金额：',u'修改金额：', amount)
        if dlg.ShowModal() != wx.ID_OK:
            return
            
        try:
            amount = float(dlg.GetValue())
        except ValueError as exp:
            kit.showExcept(exp, u'输入错误：请输入数值')
            return
     
        id = int(self.GetItem(item, self.iId).GetText())
        obj = CDataPeerFund.findObj(id)
        obj.setValue(obj.fi_money, amount)
        obj.update()
        self.refresh()

        
    def modifyLend(self, item):
        import DlgProGX
        id = int(self.GetItem(item, self.iId).GetText())
        obj = CDataPeerLend.findObj(id)
        
        dlg = DlgProGX.create(None)
        dlg.setData(proId=obj.getValue(obj.fi_proId), 
                    unit=obj.getValue(obj.fi_unit), 
                    price=obj.getValue(obj.fi_price),
                    cnt=obj.getValue(obj.fi_num))
    
        if (dlg.ShowModal() != wx.ID_OK):
            return
            
        obj.setValue(obj.fi_price, dlg.price)
        obj.setValue(obj.fi_num, dlg.cnt)
        obj.setValue(obj.fi_total, dlg.cnt*dlg.price)
        obj.update()
        
    def OnDelItem(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.MessageDialog(self, u'删除后将无法恢复，是否确认删除?',u'提示',
                                wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return
            
        unit = self.GetItem(item, self.iUnit).GetText()
        id = int(self.GetItem(item, self.iId).GetText())
        if (unit != ''):
            obj = CDataPeerLend.findObj(id)
        else:
            obj = CDataPeerFund.findObj(id)
        
        obj.delete()
    
    def getItemObj(self, item):
        unit = self.GetItem(item, self.iUnit).GetText()
        id = int(self.GetItem(item, self.iId).GetText())
        if (unit != ''):
            obj = CDataPeerLend.findObj(id)
        else:
            obj = CDataPeerFund.findObj(id)
        
        return obj

    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'all':,'peerId':}
        '''
        data = []
        
        sql = ''
        if (filter.has_key('peerId')):
            peerId = filter['peerId']
            peerObj = CDataPeer.getData({"id":peerId})#findObj(peerId)
            sql = 'peerId=%s'%filter['peerId']
        else:
            print u'未知键：%s' %filter
            return data
               
        lendList = CDataPeerLend.fetch(sql)
        for obj in lendList:
            row = []
            row.append(obj.getValue(obj.fi_id))
            row.append(peerObj.getValue(peerObj.fi_name))
            row.append(obj.getValue(obj.fi_date))
            
            if (obj.getValue(obj.fi_num) > 0.0):
                item = u'借入：'
            else:
                item = u'借出：'
            item += obj.getValue(obj.fi_proName)
            row.append(item)
            
            pro = CDataProduct.getData({"id":obj.fi_proId})#findObj(obj.getValue(obj.fi_proId))
            row.append(pro.getValue(pro.COL_SPEC))
            
            row.append(obj.getValue(obj.fi_unit))
            row.append(obj.getValue(obj.fi_num)) 
            row.append(obj.getValue(obj.fi_price))
            row.append(obj.getValue(obj.fi_total)) 
            row.append(obj.getValue(obj.fi_memo)) 
            row.append(obj.getValue(obj.fi_handler))
            row.append(obj.getValue(obj.fi_recorder))
            
            data.append(row)         
                
        fundList = CDataPeerFund.fetch(sql)
        for obj in fundList:
            row = []
            row.append(obj.getValue(obj.fi_id))
            row.append(peerObj.getValue(peerObj.fi_name))
            row.append(obj.getValue(obj.fi_date))
            
            if (obj.getValue(obj.fi_money) > 0.0):
                item = u'对方付款：%s' %obj.getAccountName()
            else:
                item = u'我方付款：%s' %obj.getAccountName()
            row.append(item)
            
            row.append('')
            row.append('') 
            row.append('')
            row.append('')
            row.append(obj.getValue(obj.fi_money)) 
            row.append(obj.getValue(obj.fi_memo)) 
            row.append(obj.getValue(obj.fi_handler))
            row.append(obj.getValue(obj.fi_recorder))
            
            data.append(row)
        return data 
            
class MySupplierListCtrl(MySortListCtrl):
    '''显示supplier列表，以供选择'''  
##    def __init__(self, parent):
##        self.cols = [(u'编号', wx.LIST_FORMAT_LEFT, 0),
##                    (u'供应商名称', wx.LIST_FORMAT_LEFT, 250),
##                    (u'简名', wx.LIST_FORMAT_LEFT, 0),
##                    (u'联系人', wx.LIST_FORMAT_LEFT, 80),
##                    (u'联系电话', wx.LIST_FORMAT_LEFT, 120),
##                    (u'期初欠款', wx.LIST_FORMAT_LEFT, 0),
##                    (u'欠款总额', wx.LIST_FORMAT_LEFT, 100),#2014-08-01
##                    (u'联系地址', wx.LIST_FORMAT_LEFT, 0),
##                    (u'电子邮件', wx.LIST_FORMAT_LEFT, 0),
##                    (u'传真', wx.LIST_FORMAT_LEFT,  0),
##                    (u'备注', wx.LIST_FORMAT_LEFT, 100)]
##            
##        MySortListCtrl.__init__(self, parent=parent,
##                        style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    def makeCols(self):
        self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerName = self.appendCol((u'供应商名称', wx.LIST_FORMAT_LEFT, 250))
        self.appendCol((u'简名', wx.LIST_FORMAT_LEFT, 0))
        self.appendCol((u'联系人', wx.LIST_FORMAT_LEFT, 80))
        self.appendCol((u'联系电话', wx.LIST_FORMAT_LEFT, 120))
        self.appendCol((u'期初欠款', wx.LIST_FORMAT_RIGHT, 0))
        self.iDebt = self.appendCol((u'欠款总额', wx.LIST_FORMAT_RIGHT, 100))
        self.appendCol((u'联系地址', wx.LIST_FORMAT_LEFT, 0))
        self.appendCol((u'电子邮件', wx.LIST_FORMAT_LEFT, 0))
        self.appendCol((u'传真', wx.LIST_FORMAT_LEFT,  0))
        self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 200))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iDebt])

        self.tStatList[self.iPeerName].SetLabel(u'共%d条记录'  %self.GetItemCount())
            
    def getSelectObj(self):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return None
        id = int(self.GetItemText(item))
        return CDataSupplier.getFirstInstance({CDataSupplier.COL_ID:id})
        
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'all':,}
        '''
        data = []
        sql = ''
        if (filter.has_key('all')): 
            # str = "'%%%s%%'"  %filter['all']
            # for field in CDataSupplier.m_fieldNames:
            #     sql += '%s like %s or ' %(field, str)
            # sql = sql[:-4]
            sql = CDataSupplier.getSearchSql(filter['all'])
        
        print sql
        
        objList = CDataSupplier.fetch(sql)
        if (objList is None):
            return data

        for obj in (objList):
            dataRow = []
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_ID))
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_NAME))
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_BREIFCODE))
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_LINKMAN))#spec
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_LMPHONE))
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_DEBT))
            #2014-08-01
            dataRow.append(obj.getDebt())
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_ADDR))
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_EMAIL))
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_FAX))#pro memo
            dataRow.append(obj.getFieldVal(index=CDataSupplier.COL_MEMO))

            data.append(dataRow)
             
        return data
    
class MyListCtrlSupplierProRecent(MySortListCtrl):
    '''根据指定的供应商呈现最近采购历史信息，以便于直接选择用于新的采购订单'''
##    def __init__(self, parent, pos=wx.DefaultPosition,size=wx.DefaultSize):
##        self.cols = [(u'最近采购单号', wx.LIST_FORMAT_LEFT, 0),
##                    (u'编号', wx.LIST_FORMAT_LEFT, 0),
##                    (u'名称', wx.LIST_FORMAT_LEFT, 125),
##                    (u'规格', wx.LIST_FORMAT_LEFT,  125), 
##                    (u'单位', wx.LIST_FORMAT_LEFT,  50), 
##                    (u'最近进价', wx.LIST_FORMAT_RIGHT, 80),
##                    (u'采购总数量', wx.LIST_FORMAT_RIGHT, 0),
##                    (u'采购总金额', wx.LIST_FORMAT_RIGHT, 0)]
##        
##        [self.iBillId,self.iProId,self.iName,self.iSpec,self.iUnit,
##        self.iPrice,self.iCnt,self.iAmount] = [i for i in range(len(self.cols))]
##        
##        MySortListCtrl.__init__(self, parent,pos=pos,size=size,
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    def makeCols(self):
        cols = [(u'最近采购单号', wx.LIST_FORMAT_LEFT, 0),
                (u'编号', wx.LIST_FORMAT_LEFT, 0),
                (u'名称', wx.LIST_FORMAT_LEFT, 120),
                (u'规格', wx.LIST_FORMAT_LEFT,  120), 
                (u'单位', wx.LIST_FORMAT_LEFT,  40), 
                (u'进价', wx.LIST_FORMAT_RIGHT, 50),
                (u'库存', wx.LIST_FORMAT_RIGHT, 50),
                (u'仓位', wx.LIST_FORMAT_RIGHT, 50),
                (u'采购总数量', wx.LIST_FORMAT_RIGHT, 0),
                (u'采购总金额', wx.LIST_FORMAT_RIGHT, 0),
                (u'运费', wx.LIST_FORMAT_LEFT, 50),
                (u'备注', wx.LIST_FORMAT_LEFT, 100),
                (u'启用', wx.LIST_FORMAT_RIGHT, 0),
                (u'预警线', wx.LIST_FORMAT_RIGHT, 0)]
        
        [self.iBillId,self.iProId,self.iName,self.iSpec,self.iUnit,
        self.iPrice,self.iQty,self.iPosition,self.iCnt,
        self.iAmount, self.iCharge, self.iMemo, self.iOnuse,self.iWarnStock] = self.appendColList(cols)
        
        self.setFilter()
        
    def setViewProSelect(self):
        self.SetColumnWidth(self.iBillId, 130)
        self.SetColumnWidth(self.iName, 110)
        self.SetColumnWidth(self.iCnt, 100)
        self.SetColumnWidth(self.iAmount, 100)
        self.dateStart = 'CG-20000101-00001' # 默认显示所有
    
    def getProSaleInfo(self, item=-1):
        '''
            item - -1默认为选中项
        '''
        if (item == -1):
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                print 'Error unselect item'
                return []
            
        proId = int(self.GetItem(item, self.iProId).GetText())
        proName = self.GetItem(item, self.iName).GetText()
        unit = self.GetItem(item, self.iUnit).GetText()
        price = float(self.GetItem(item, self.iPrice).GetText())
        charge = float(self.GetItem(item, self.iCharge).GetText()) if self.GetItem(item, self.iCharge).GetText() != '' else 0.0
        memo = self.GetItem(item, self.iMemo).GetText()
        return [proId, proName, unit, price, charge, memo]
    
    # def setFilter(self, keywordIds=[], categoryIds=[]):
    #     '''
    #         设置过滤条件--关键字、类别
    #         代码拷贝自MyProductListCtrl
    #     '''
    #     self.curCategoryIds = categoryIds
    #     self.curKeywordIds = keywordIds

    # def matchExtraFilter(self, proObj):
    #     if not (self.curCategoryIds):
    #         return True
        
    #     categoryId = proObj.getValue(proObj.COL_CATEGORYID)
    #     return categoryId in self.curCategoryIds

    # def convert(self, filter={}):
    #     '''根据filter显示数据
    #         filter - {'peerId':xx}
    #     '''
    #     data = []            
    #     proList = CDataSupplier.getProRecent(filter['peerId'])

    #     for item in proList:
    #         billId,proId,proName,unit,price,cnt,amount,quantity,position,charge,memo = item
            
    #         proObj = CDataProduct.getData({'id':proId})
    #         if (proObj is None):
    #             print '[Error] None id %d' %proId

    #         if not (self.matchExtraFilter(proObj)):
    #             continue

    #         proName = proObj.getValue(CDataProduct.COL_NAME)
    #         proSpec = proObj.getValue(CDataProduct.COL_SPEC)
    #         data.append([billId,proId,proName,proSpec,unit,price,quantity,position,cnt,amount,charge,memo])
        
    #     return data

    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if self.GetItem(index, self.iOnuse).GetText() != 'O':
                self.SetItemBackgroundColour(index, wx.Colour(250, 140, 217)) # 紫色
            elif float(self.GetItem(index, self.iQty).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            elif float(self.GetItem(index, self.iCnt).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(200, 200, 200)) # 灰色
            elif float(self.GetItem(index, self.iQty).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)

    def setFilter(self, keywordIds=[], categoryIds=[], sku=((),())):
        '''转换条件为sql形式'''
        
        self.filter_keywordIds = keywordIds
        self.filter_categoryIds = categoryIds
        self.filterSql = ''
        
        #根据关键字查找proId
        if (len(keywordIds) != 0):
##            proIds = []
##            sql = 'keywordId in (' + self.concat(keywordIds, ',') +')'
##            proLabelObjs = CDataProLabel.fetch(sql)
##            for obj in proLabelObjs:
##                proIds.append(obj.getFieldVal(index=CDataProLabel.COL_PROID))
        
            proIds = CDataProLabel.getProId(keywordIds, True)
            if (len(proIds) != 0):
                self.filterSql += 'id in (' + self.concat(proIds, ',') + ')'
            else:
                #没有符合关键字的产品，应该不显示数据
                self.filterSql += 'id in (0)'
            
        #根据分类查找    
        if (len(categoryIds) != 0):
            if (self.filterSql != ''):
                self.filterSql += ' and '
            self.filterSql += 'categoryId in (' + self.concat(categoryIds, ',') + ')'
        
        #print sku
        if (len(sku[1]) > 0):
            #print sku[1]
            sku_item = tuple([",".join(i) for i in sku[1]])
            # if len(sku[1][0]) == 1:
                # sku_item = sku[1]
            # else:
                # sku_item = tuple([",".join(i) for i in sku[1]])
            #print sku_item
            if (self.filterSql != ''):
                self.filterSql += ' and '
            self.filterSql += " d.proId IN "\
                " (SELECT pro_id FROM ("\
                " SELECT pro_id,GROUP_CONCAT(sku_id ORDER BY group_id) as sku"\
                " FROM product_sku LEFT JOIN sku_item ON sku_id=sku_item.id"\
                " WHERE group_id IN (%s)"\
                " GROUP BY pro_id ) t WHERE sku in %s)" \
                %(",".join([str(i) for i in sku[0]])
                 , str(sku_item).replace("u'","'") if len(sku_item) > 1 else "('%s')"%sku_item)

    def concat(self, list, separator):
        str = ''
        for i in range(len(list)):
            str += '%d,' %list[i]
    
        return str[:-1]

      
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx}
        '''
        self.m_peerId = filter['peerId']
        return CDataSupplier.GetLatestProList(filter['peerId'], self.filterSql)#self.curCategoryIds)

    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)
        
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())
    
class MyListCtrlProPurDetail(MySortListCtrl):
    '''显示某产品的采购历史明细，可以指定供应商'''
##    def __init__(self, parent):
##        self.cols =[]
##    
##        self.iPeer = self.appendCol((u'供应商', wx.LIST_FORMAT_LEFT, 115))
##        self.iBillId = self.appendCol((u'单据号', wx.LIST_FORMAT_LEFT, Width_BillId))
##        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 50))
##        self.iCnt = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 60))
##        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 60))
##        self.iAmount = self.appendCol((u'金额', wx.LIST_FORMAT_RIGHT, 80))
##        
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    def makeCols(self):
        self.iPeer = self.appendCol((u'供应商', wx.LIST_FORMAT_LEFT, 115))
        #self.iBillId = self.appendCol((u'单据号', wx.LIST_FORMAT_LEFT, Width_BillId))
        self.iBillId = self.appendCol((u'日期', wx.LIST_FORMAT_LEFT, 80))
        self.iName = self.appendCol((u'品名', wx.LIST_FORMAT_LEFT, 0))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 0))
        self.iCnt = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 50))
        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 50))
        self.iCharge = self.appendCol((u'运费', wx.LIST_FORMAT_RIGHT, 0))
        self.iAmount = self.appendCol((u'入库价', wx.LIST_FORMAT_RIGHT, 60))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 200))        
        self.iPriceByWeight = self.appendCol((u'重量单价', wx.LIST_FORMAT_LEFT, 50))
        self.iPriceByLength = self.appendCol((u'长度单价', wx.LIST_FORMAT_LEFT, 50))
        self.iPriceByArea = self.appendCol((u'平方单价', wx.LIST_FORMAT_LEFT, 50))
        self.iWhIn = self.appendCol((u'入库仓库', wx.LIST_FORMAT_LEFT, 60))
    
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iCnt, self.iAmount])
    
    def setViewProSelect(self):
        self.SetColumnWidth(self.iPeer, 0)
    
    def appendCol(self, colInfo):
        self.cols.append(colInfo)
        return len(self.cols) - 1
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            #if self.GetItem(index, self.iWhIn).GetText() == "" and self.GetItem(index, self.iBillId).GetText() > "CJ-20240110":
            if self.GetItem(index, self.iWhIn).GetText() == "" and self.GetItem(index, self.iBillId).GetText() > "20240110":
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140))
            else:
                self.resetBgcolour(index)

    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx, 'proId':xx}, peerId 可选
        '''
        data = []            
        
        proObj = CDataProduct.getData({'id':filter['proId']})
        weight = proObj.getValue(CDataProduct.COL_WEIGHT)
        area = proObj.getValue(CDataProduct.COL_AREA)
        length = proObj.getValue(CDataProduct.COL_LENGTH)

        if (filter.has_key('peerId')):
            peerId = filter['peerId']
            #peerName = CDataSupplier.findItemValue({CDataSupplier.COL_ID:peerId},
            #                                            CDataSupplier.COL_NAME)  
            peerName = CDataSupplier.getName(peerId)
            list = CDataPurDetail.getProSaleInfo(filter['proId'], peerId)                                            
            for proName,unit,price,billId,num,total,memo,quantity,position,charge,wh_in in list:                
                             
                data.append([peerName,billId,proName,unit,num,price,charge,price+charge,memo
                    ,float("%.2f"%(price/weight)) if weight > 0 else 0
                    ,float("%.2f"%(price/length)) if length > 0 else 0
                    ,float("%.2f"%(price/area)) if area > 0 else 0
                    ,wh_in])
          
        else:
            list = CDataPurDetail.getProSaleInfo(filter['proId'])
            for proName,unit,price,billId,num,total,peerId,memo,quantity,position,charge,wh_in in list:                
                #peerName = CDataSupplier.findItemValue({CDataSupplier.COL_ID:peerId},
                #                                        CDataSupplier.COL_NAME) 
                peerName = CDataSupplier.getName(peerId)                
                data.append([peerName,billId,proName,unit,num,price,charge,price+charge,memo
                    ,float("%.2f"%(price/weight)) if weight > 0 else 0
                    ,float("%.2f"%(price/length)) if length > 0 else 0
                    ,float("%.2f"%(price/area)) if area > 0 else 0
                    ,wh_in])  
        
        return data

class MyListCtrlProSaleDetail(MySortListCtrl):
    '''显示某产品的销售历史明细，可以指定供应商'''
##    def __init__(self, parent):
##        self.cols =[]
##
##        self.ClsPeer = CDataCustomer
##        self.ClsDetail = CDataSaleDetail
##            
##        self.iPeer = self.appendCol((u'客户', wx.LIST_FORMAT_LEFT, 115))
##        self.iBillId = self.appendCol((u'单据号', wx.LIST_FORMAT_LEFT, Width_BillId))
##        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 50))
##        self.iCnt = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 60))
##        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 60))
##        self.iAmount = self.appendCol((u'金额', wx.LIST_FORMAT_RIGHT, 80))
##        
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    ClsPeer = CDataCustomer
    ClsDetail = CDataSaleDetail
        
    def makeCols(self):
        self.iPeer = self.appendCol((u'客户', wx.LIST_FORMAT_LEFT, 115))
        #self.iBillId = self.appendCol((u'单据号', wx.LIST_FORMAT_LEFT, Width_BillId))
        self.iBillId = self.appendCol((u'单据号', wx.LIST_FORMAT_LEFT, 120))
        self.iProname = self.appendCol((u'品名', wx.LIST_FORMAT_LEFT, 0))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 0))
        self.iCnt = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 50))
        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 50))
        self.iAmount = self.appendCol((u'金额', wx.LIST_FORMAT_RIGHT, 60))
        self.iState = self.appendCol((u'状态', wx.LIST_FORMAT_RIGHT, 0))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 150))
        self.iDlvy = self.appendCol((u'配送', wx.LIST_FORMAT_LEFT, 50))
        self.iPriceByWeight = self.appendCol((u'重量单价', wx.LIST_FORMAT_LEFT, 50))
        self.iPriceByLength = self.appendCol((u'长度单价', wx.LIST_FORMAT_LEFT, 50))
        self.iPriceByArea = self.appendCol((u'平方单价', wx.LIST_FORMAT_LEFT, 50))
        
    
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iCnt, self.iAmount])
        
    def setViewProSelect(self):
        self.SetColumnWidth(self.iPeer, 0)
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if self.GetItem(index, self.iState).GetText() == "" and self.GetItem(index, self.iCnt).GetText() != "0":
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140))
            else:
                self.resetBgcolour(index)
                
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx, 'proId':xx}, peerId 可选
        '''
        data = []

        proObj = CDataProduct.getData({'id':filter['proId']})
        weight = proObj.getValue(CDataProduct.COL_WEIGHT)
        area = proObj.getValue(CDataProduct.COL_AREA)
        length = proObj.getValue(CDataProduct.COL_LENGTH)            
        
        if (filter.has_key('peerId')):
            peerId = filter['peerId']
            #peerName = self.ClsPeer.findItemValue({self.ClsPeer.COL_ID:peerId},
            #                                            self.ClsPeer.COL_NAME)  
            peerName =  self.ClsPeer.getName(peerId)
            list = CDataSaleDetail.getProSaleInfo(proId=filter['proId'],
                peerId=peerId)                                            
            for proName,unit,price,billId,num,total,state,memo,quantity,position,dlvyInfo in list:                
                             
                data.append([peerName,billId,proName,unit,num,price,total,state,memo,dlvyInfo
                    ,float("%.2f"%(price/weight)) if weight > 0 else 0
                    ,float("%.2f"%(price/length)) if length > 0 else 0
                    ,float("%.2f"%(price/area)) if area > 0 else 0])
        
        else:
            list = CDataSaleDetail.getProSaleInfo(proId=filter['proId'],
                regionId = filter['regionId'] if filter.has_key('regionId') else -1,
				show_peihuo = True if filter.has_key('showPeiHuo') else False)
            for proName,unit,price,billId,num,total,peerId,state,memo,quantity,position,dlvyInfo in list:                
                #peerName = self.ClsPeer.findItemValue({self.ClsPeer.COL_ID:peerId},
                #                                        self.ClsPeer.COL_NAME)                
                peerName =  self.ClsPeer.getName(peerId)
                data.append([peerName,billId,proName,unit,num,price,total,state,memo,dlvyInfo
                    ,float("%.2f"%(price/weight)) if weight > 0 else 0
                    ,float("%.2f"%(price/length)) if length > 0 else 0
                    ,float("%.2f"%(price/area)) if area > 0 else 0])  
        
        return data
 
                     
class MyListCtrlCustProRecent(MySortListCtrl):
    '''显示订单列表'''

    include_menu = True
    
    def makeMenu(self):     
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)

        self.menu.AppendSeparator()
        MySortListCtrl.appendCommonMenu(self)
    
       
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())
    
    def getPeerId(self, item=-1):
        return  self.m_peerId
        
    def __init__(self, parent, pos=wx.DefaultPosition,size=wx.DefaultSize):
##        self.cols = [(u'最近销售单号', wx.LIST_FORMAT_LEFT, 0),
##                    (u'编号', wx.LIST_FORMAT_LEFT, 0),
##                    (u'名称', wx.LIST_FORMAT_LEFT, 125),
##                    (u'规格', wx.LIST_FORMAT_LEFT,  125), 
##                    (u'单位', wx.LIST_FORMAT_LEFT,  50), 
##                    (u'最近售价', wx.LIST_FORMAT_RIGHT, 80),
##                    (u'销售总数量', wx.LIST_FORMAT_RIGHT, 0),
##                    (u'销售总金额', wx.LIST_FORMAT_RIGHT, 0)]
##        
##        [self.iBillId,self.iProId,self.iName,self.iSpec,self.iUnit,
##        self.iPrice,self.iCnt,self.iAmount] = [i for i in range(len(self.cols))]
        
        MySortListCtrl.__init__(self, parent,pos=pos,size=size, 
                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
        self.setFilter()
        self.dateStart = 'XS-' + (datetime.date.today() - datetime.timedelta(days=365)).strftime("%Y-%m-%d") + '-00001'
    
    def makeCols(self):
        cols = [(u'最近销售单号', wx.LIST_FORMAT_LEFT, 0),
                    (u'编号', wx.LIST_FORMAT_LEFT, 0),
                    (u'名称', wx.LIST_FORMAT_LEFT, 125),
                    (u'规格', wx.LIST_FORMAT_LEFT,  125), 
                    (u'单位', wx.LIST_FORMAT_LEFT,  40), 
                    (u'售价', wx.LIST_FORMAT_RIGHT, 50),
                    (u'库存', wx.LIST_FORMAT_RIGHT, 50),
                    (u'仓位', wx.LIST_FORMAT_RIGHT, 0),
                    (u'销售总数量', wx.LIST_FORMAT_RIGHT, 0),
                    (u'销售总金额', wx.LIST_FORMAT_RIGHT, 0),
                    (u'启用', wx.LIST_FORMAT_RIGHT, 0),
                    (u'预警线', wx.LIST_FORMAT_RIGHT, 0)]
                
        [self.iBillId,self.iProId,self.iName,self.iSpec,self.iUnit,
        self.iPrice,self.iQty,self.iPosition,self.iCnt,
        self.iAmount,self.iOnuse,self.iWarnStock] = self.appendColList(cols)
         
    def setViewProSelect(self):
        self.SetColumnWidth(self.iBillId, 130)
        self.SetColumnWidth(self.iName, 110)
        self.SetColumnWidth(self.iCnt, 100)
        self.SetColumnWidth(self.iAmount, 100)
        self.dateStart = 'XS-20000101-00001' # 默认显示所有
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if self.GetItem(index, self.iOnuse).GetText() != 'O':
                self.SetItemBackgroundColour(index, wx.Colour(250, 140, 217)) # 紫色
            elif float(self.GetItem(index, self.iQty).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            elif float(self.GetItem(index, self.iCnt).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(200, 200, 200)) # 灰色
            elif float(self.GetItem(index, self.iQty).GetText()) < float(self.GetItem(index, self.iWarnStock).GetText()):
                self.SetItemBackgroundColour(index, wx.Colour(255, 255, 100)) # 黄色
            else:
                self.resetBgcolour(index)

            
    def getProSaleInfo(self, item=-1):
        if (item == -1):
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                print 'Error unselect item'
                return []
            
        proId = int(self.GetItem(item, self.iProId).GetText())
        proName = self.GetItem(item, self.iName).GetText()
        unit = self.GetItem(item, self.iUnit).GetText()
        price = float(self.GetItem(item, self.iPrice).GetText())
        return [proId, proName, unit, price]

    # def setFilter(self, keywordIds=[], categoryIds=[]):
    #     '''
    #         设置过滤条件--关键字、类别
    #         代码拷贝自MyProductListCtrl
    #     '''
    #     self.curCategoryIds = categoryIds
    #     self.curKeywordIds = keywordIds
    def setFilter(self, keywordIds=[], categoryIds=[], sku=((),())):
        '''转换条件为sql形式'''
        
        self.filter_keywordIds = keywordIds
        self.filter_categoryIds = categoryIds
        self.filterSql = ''
        
        #根据关键字查找proId
        if (len(keywordIds) != 0):
##            proIds = []
##            sql = 'keywordId in (' + self.concat(keywordIds, ',') +')'
##            proLabelObjs = CDataProLabel.fetch(sql)
##            for obj in proLabelObjs:
##                proIds.append(obj.getFieldVal(index=CDataProLabel.COL_PROID))
        
            proIds = CDataProLabel.getProId(keywordIds, True)
            if (len(proIds) != 0):
                self.filterSql += 'id in (' + self.concat(proIds, ',') + ')'
            else:
                #没有符合关键字的产品，应该不显示数据
                self.filterSql += 'id in (0)'
            
        #根据分类查找    
        if (len(categoryIds) != 0):
            if (self.filterSql != ''):
                self.filterSql += ' and '
            self.filterSql += 'categoryId in (' + self.concat(categoryIds, ',') + ')'
        
        #print sku
        if (len(sku[1]) > 0):
            #print sku[1]
            sku_item = tuple([",".join(i) for i in sku[1]])
            # if len(sku[1][0]) == 1:
                # sku_item = sku[1]
            # else:
                # sku_item = tuple([",".join(i) for i in sku[1]])
            #print sku_item
            if (self.filterSql != ''):
                self.filterSql += ' and '
            self.filterSql += " d.proId IN "\
                " (SELECT pro_id FROM ("\
                " SELECT pro_id,GROUP_CONCAT(sku_id ORDER BY group_id) as sku"\
                " FROM product_sku LEFT JOIN sku_item ON sku_id=sku_item.id"\
                " WHERE group_id IN (%s)"\
                " GROUP BY pro_id ) t WHERE sku in %s)" \
                %(",".join([str(i) for i in sku[0]])
                 , str(sku_item).replace("u'","'") if len(sku_item) > 1 else "('%s')"%sku_item)

    def concat(self, list, separator):
        str = ''
        for i in range(len(list)):
            str += '%d,' %list[i]
    
        return str[:-1]


    def matchExtraFilter(self, proObj):
        if not (self.curCategoryIds):
            return True
        
        categoryId = proObj.getValue(proObj.COL_CATEGORYID)
        return categoryId in self.curCategoryIds
      
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx}
        '''
        self.m_peerId = filter['peerId']
        return CDataCustomer.GetLatestProList(filter['peerId'],self.dateStart, self.filterSql)#self.curCategoryIds)

        self.m_peerId = filter['peerId']
        data = []
        proList = CDataCustomer.getProDetail(filter['peerId'], 
            self.dateStart if filter['peerId'] != 1292 else 'XS-' + (datetime.date.today() - datetime.timedelta(days=30)).strftime("%Y-%m-%d") + '-00001')

        for item in proList:
            billId,proId,proName,unit,price,cnt,amount,quantity,position = item
            
            proObj = CDataProduct.getData({'id':proId})
            if (proObj is None):
                print '[Error] None id %d' %proId
            
            if not (self.matchExtraFilter(proObj)):
                continue
                
            proSpec = proObj.getValue(CDataProduct.COL_SPEC)
            data.append([billId,proId,proName,proSpec,unit,price,quantity,position,cnt,amount])
        
        return data

class MyListCtrlPurchasePlan(MySortListCtrl):
    ''' 采购计划表 '''

    [TYPE_PLANED, TYPE_ORDERED, TYPE_SHIPPED] = [i for i in range(3)]
    
    include_menu = True    
    def makeMenu(self):
        '''由子类重载该函数，以定制菜单。
            可以在子类中调用MySortListCtrl.appendCommonMenu以默认添加以下菜单'''
        item = self.menu.Append(-1, u'修改记录')
        self.Bind(wx.EVT_MENU, self.OnModify, item) 
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'编辑备注')
        self.Bind(wx.EVT_MENU, self.OnEditMemo, item) 
    
        self.menu.AppendSeparator()    

        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'删除记录')
            self.Bind(wx.EVT_MENU, self.OnDelItem, item) 
        
            self.menu.AppendSeparator()

            item = self.menu.Append(-1, u'全部删除')
            self.Bind(wx.EVT_MENU, self.OnDelAll, item) 
        
            self.menu.AppendSeparator()          
    
        # 二级菜单 - 编辑
        editMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'修改状态', editMenu) 
        
        editMenu.AppendSeparator()
        item = editMenu.Append(-1, u'准备订货')
        self.Bind(wx.EVT_MENU, self.OnMenuStatusPlaned, item) 
        
        item = editMenu.Append(-1, u'已经下单')
        self.Bind(wx.EVT_MENU, self.OnMenuStatusOrdered, item) 
        
        item = editMenu.Append(-1, u'已经发货')
        self.Bind(wx.EVT_MENU, self.OnMenuStatusShipped, item) 
        
        
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
    
    def OnMenuStatusPlaned(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        id = int(self.GetItem(item, self.iId).GetText())
        CDataProduct.update_purchase_plan(id=id, status=self.TYPE_PLANED)
        #self.refresh()    
        self.GetParent().GetParent().GetParent().GetParent().RefreshPurchasePlan()
    
    def OnMenuStatusOrdered(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        id = int(self.GetItem(item, self.iId).GetText())
        CDataProduct.update_purchase_plan(id=id, status=self.TYPE_ORDERED)
        #self.refresh()    
        self.GetParent().GetParent().GetParent().GetParent().RefreshPurchasePlan()
    
    def OnMenuStatusShipped(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        id = int(self.GetItem(item, self.iId).GetText())
        CDataProduct.update_purchase_plan(id=id, status=self.TYPE_SHIPPED)
        #self.refresh()    
        self.GetParent().GetParent().GetParent().GetParent().RefreshPurchasePlan() 
        
    def OnEditMemo(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        memo = self.GetItem(item, self.iMemo).GetText()
        dlg = wx.TextEntryDialog(
                self, u'修改备注：',u'修改备注：', memo)
        if dlg.ShowModal() == wx.ID_OK:        
            id = int(self.GetItem(item, self.iId).GetText())
            CDataProduct.update_purchase_plan(id=id, memo=dlg.GetValue())
            self.SetStringItem(item, self.iMemo, dlg.GetValue())
            
    def OnModify(self, event):
        import DlgProGX
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        id = int(self.GetItem(item, self.iId).GetText())
        proId = int(self.GetItem(item, self.iProId).GetText())
        
        dlg = DlgProGX.create(self.GetParent())
        dlg.setData(proId=proId, 
                    unit=self.GetItem(item, self.iUnit).GetText(), 
                    price=float(self.GetItem(item, self.iPrice).GetText()),
                    cnt=float(self.GetItem(item, self.iQty).GetText()))
    
        if (dlg.ShowModal() == wx.ID_OK):
            CDataProduct.update_purchase_plan(id=id, qty=dlg.cnt, price=dlg.price)
            self.SetStringItem(item, self.iQty, str(dlg.cnt))
            self.SetStringItem(item, self.iPrice, str(dlg.price))
            self.SetStringItem(item, self.iTotal, str(dlg.price*dlg.cnt))
        
        
    def OnDelItem(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        id = int(self.GetItem(item, self.iId).GetText())
        
        dlg = wx.MessageDialog(self, u'删除后将无法恢复，是否确认删除?',u'提示',
                                wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_YES):
            CDataProduct.delete_purchase_plan(id)
            self.refresh()
            
    def OnDelAll(self, event):
       
        dlg = wx.MessageDialog(self, u'删除后将无法恢复，是否确认删除?',u'提示',
                                wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_YES):
            CDataProduct.delete_purchase_plan_by_type(self.m_type)
            self.refresh()    
        
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())
    
    
    def __init__(self, parent, type_plan, pos=wx.DefaultPosition,size=wx.DefaultSize):

        MySortListCtrl.__init__(self, parent,pos=pos,size=size, 
                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
        self.m_type = type_plan
        self.m_categoryIds  = None
    
    def makeCols(self):
        cols = [(u'ID', wx.LIST_FORMAT_LEFT, 0),
                    (u'商品ID', wx.LIST_FORMAT_LEFT, 0),
                    (u'商品名称', wx.LIST_FORMAT_LEFT, 120),
                    (u'商品规格', wx.LIST_FORMAT_LEFT,  120), 
                    (u'单位', wx.LIST_FORMAT_LEFT,  40), 
                    (u'单价', wx.LIST_FORMAT_RIGHT, 50),
                    (u'数量', wx.LIST_FORMAT_RIGHT, 50),                    
                    (u'总价', wx.LIST_FORMAT_RIGHT, 50),
                    (u'备注', wx.LIST_FORMAT_RIGHT, 50),
                    (u'仓位', wx.LIST_FORMAT_RIGHT, 0),
                    (u'库存', wx.LIST_FORMAT_RIGHT, 0)]
                
        [self.iId,self.iProId,self.iName,self.iSpec,self.iUnit,
        self.iQty,self.iPrice,self.iTotal,self.iMemo,self.iPosition,self.iOnhand] = self.appendColList(cols)
    
    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iQty).GetText()) <= 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 无库存，红色
            else:
                self.resetBgcolour(index)
                
    def setFilter(self, categoryIds):
        self.m_categoryIds = categoryIds
        
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx}
        '''
 
        return CDataProduct.get_purchase_plan(self.m_type
            , self.m_categoryIds )
    
class MyListCtrlSaleOrderTemp(MySortListCtrl):
    '''显示订单列表'''

    include_menu = True
    include_statBar = True
    xlsFile = u'销售草稿单.xlsx'
    
##    def __init__(self, parent):
##        
##        self.makeCols() # 改行重构后消失
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    def makeCols(self):
        #self.cols = [] # 改行重构后消失
        self.iBillId = self.appendCol((u'订单号', wx.LIST_FORMAT_LEFT, 180))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 120))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iPaid = self.appendCol((u'已付金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iUnpaid = self.appendCol((u'未付金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iDiscount = self.appendCol((u'优惠金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iDate = self.appendCol((u'订单日期', wx.LIST_FORMAT_LEFT,  90))
        self.iDlvy = self.appendCol((u'配送方式', wx.LIST_FORMAT_LEFT,  -1))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT,  -1))
        self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT,  -1))
        self.iOperator = self.appendCol((u'操作员', wx.LIST_FORMAT_LEFT, -1))

    def makeMenu(self):
        item = self.menu.Append(-1, u'编辑审核')
        self.Bind(wx.EVT_MENU, self.OnMenuAudit, item)  
        
        self.menu.AppendSeparator()
          
        # 二级菜单 - 删除  主要是为了避免误点击
        delMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'删除订单', delMenu)
        
        item = delMenu.Append(-1, u'删除订单')
        self.Bind(wx.EVT_MENU, self.OnMenuDel, item) 
        
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
    
    def OnMenuDel(self, event):
        if not PermitManager.accessTest(const.PERMIT_DEL_ORDER_TEMP):
            return
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.MessageDialog(self, u'删除后将无法恢复，是否确认删除?',u'提示',
                                wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return
            
        billId = self.getBillId(item)
        CDataSaleOrderTemp.deleteBill(billId)
        #看看是不是会影响效率，订单页面似乎没必要保持显示（会产生同步问题）
        self.reloadData()
            
            
    def OnMenuAudit(self, event):
        if not PermitManager.accessTest(const.PERMIT_MODIFY_ORDER_TEMP):
            return
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        billId = self.GetItem(item, self.iBillId).GetText()
        #CDataSaleOrderTemp.audit(billId)
    
        kit.getRootWin(self).addPageSale(billId, draft=True)
        
                
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iPaid, self.iUnpaid, self.iDiscount])
        
        # 初始化时，因为listctrl没有数据，所以statBar的大小有问题，不显示
        # 在刷新出数据时，重设位置
        #self.resetStatPos()
            
    def getBillId(self, item):
        return self.GetItem(item, self.iBillId).GetText()
    
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {}
        '''
        data = []
        return[]
        #print (u'MyListCtrlSaleOrderTemp', CDataSaleOrderTemp.getObjList())
        for saleOrder in (CDataSaleOrderTemp.getObjList()):
            dataRow = []
            dataRow.append(saleOrder.getFieldVal('id'))
            
            cust = CDataCustomer.getData({'id':saleOrder.getFieldVal('peerId')})
            if cust is None:
                print 'Error:None cust %d' %saleOrder.getFieldVal('peerId')
                dataRow.append('None')
            else:
                dataRow.append(cust.getFieldVal('name'))
            
            
            #dataRow.append(saleOrder.getFieldVal('paid'))
            #dataRow.append(saleOrder.getFieldVal('unpaid'))
            #paid = saleOrder.getFieldVal('paid')
            paid = saleOrder.getPaid()
            total = saleOrder.getFieldVal('total')
            discount = saleOrder.getFieldVal('discount')
            #unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
            unpaid = saleOrder.getUnpaid()
            dataRow.append(total)
            dataRow.append(paid)
            dataRow.append(unpaid)
            dataRow.append(discount)
            
            dataRow.append(saleOrder.getFieldVal('billDate'))
            dataRow.append(saleOrder.getFieldVal('dlvyAddr'))
            dataRow.append(saleOrder.getFieldVal('memo'))
            dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_HANDLERID)))
            dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_RECOREDERID)))
          
            data.append(dataRow)
            
        return data

class MyListCtrlSaleOrderDetailTemp(MySortListCtrl):
    
    '''显示订单内容'''
##    def __init__(self, parent):
##        
##        self.makeCols() # 该行重构后消失
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum,self.iTotal])

        self.tStatList[self.iProId].SetLabel(u'共%d条记录'  %self.GetItemCount())
        
    def makeCols(self):
        #self.cols = [] # 该行重构后消失
        self.iProId = self.appendCol((u'商品编号', wx.LIST_FORMAT_LEFT, -1))
        self.iProName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 120))
        self.iProSpec = self.appendCol((u'商品规格', wx.LIST_FORMAT_LEFT,  120))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT,  40))
        self.iNum = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT,  -1))
        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, -1))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT,  200))

    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'billId':}
        '''
        data = []
        
        filterSql = "billId='%s'"  %filter['billId']
        
        objList = CDataSaleDetailTemp.fetch(filterSql)
        if (objList is None):
            return data

        for saleDetail in (objList):
            dataRow = []
            proId = saleDetail.getFieldVal('proId')
            proObj = CDataProduct.getInstance({'id':proId})
            dataRow.append(proId)
            dataRow.append(saleDetail.getFieldVal('proName'))
            dataRow.append(proObj.getFieldVal('spec'))#spec
            dataRow.append(saleDetail.getFieldVal('unit'))
            dataRow.append(saleDetail.getFieldVal('num'))
            dataRow.append(saleDetail.getFieldVal('price'))
            dataRow.append(saleDetail.getFieldVal('total'))
            dataRow.append(proObj.getFieldVal('memo'))#pro memo

            data.append(dataRow)
             
        return data

    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)
        
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())
        
class MyListCtrlOrderAmountAllocted(MySortListCtrl):
    '''显示订单付款情况，用来替换grid'''
    
    #[Type_Customer, Type_Supplier] = [i for i in range(2)]
    include_menu = True
    include_statBar = True
    
    def __init__(self, parent, ClsPeer):
        
        self.ClsPeer = ClsPeer
        if(self.ClsPeer == CDataCustomer):
            #self.ClsPeer = CDataCustomer
            self.ClsOrder = CDataSaleOrder
            self.ClsVoucher = CDataVoucher
            self.ClsFund = CRelFundCustomer
            
        elif(self.ClsPeer == CDataSupplier):
            #self.ClsPeer = CDataSupplier
            self.ClsOrder = CDataPurOrder
            self.ClsVoucher = CDataVoucherSupplier
            self.ClsFund = CRelFundSupplier
            
        #self.makeCols() # 该行重构后消失
        MySortListCtrl.__init__(self, parent, 
                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)#|wx.LC_SORT_DESCENDING)
    
    def makeCols(self):
        #self.cols = [] # 该行重构后消失
        self.iBillId = self.appendCol((u'单据编号', wx.LIST_FORMAT_LEFT, 170))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_LEFT, -1))
        #self.iPaid = self.appendCol((u'已付金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iDiscount = self.appendCol((u'优惠金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iAlloctExtra = self.appendCol((u'其他分配', wx.LIST_FORMAT_RIGHT,  -1))
        self.iAlloct = self.appendCol((u'本次分配', wx.LIST_FORMAT_RIGHT, -1))
        self.iUnpaid = self.appendCol((u'未付余额', wx.LIST_FORMAT_RIGHT,  -1))
        if(self.ClsPeer == CDataCustomer):
            self.iDlvy = self.appendCol((u'配送方式', wx.LIST_FORMAT_LEFT,  100))
            self.iState = self.appendCol((u'状态', wx.LIST_FORMAT_LEFT,  40))
            self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT,  100))
            self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT,  60))

        
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iUnpaid, self.iDiscount,self.iAlloct])
    
    def convert(self, filter={}):
        '''根据具体呈现，获取数据库数据并转换为二维数据数组
            filter - {'peerId':xx, 'voucherId':xx, 'show':all/unpaid/alloct}
        '''
        if (filter.has_key('peerId')):
            peerId = filter['peerId']
        elif(filter.has_key('voucherId')):
            #voucherObj = self.ClsVoucher.findObj(filter['voucherId'])
            #peerId = voucherObj.getValue(voucherObj.iPeerId)
            dataList = []
            dataList = self.ClsVoucher.get_alloct(filter['voucherId'])
            return dataList
        else:
            print ('lost dict key')

        #objList = self.ClsOrder.getObjs({self.ClsOrder.COL_PEERID:peerId})
        objList = self.ClsOrder.fetch('peerId=%d'%peerId)
        
        data = []
        for bill in (objList):
            if (filter.has_key('show') and filter['show'] == 'unpaid'):
                if abs(bill.getUnpaid()) < 0.01:
                    continue
                
            #dataRow = ['']*self.GetColumnCount()
            dataRow = []
            
            billId = bill.getValue(bill.COL_ID)
                
            # 编辑voucher时，设置该order的分配金额alloct，同时修改paid显示
            alloct = 0.0
            if (filter.has_key('voucherId')):
                fund = self.ClsFund.getObjs({self.ClsFund.COL_BILLID:billId,
                                        self.ClsFund.COL_VOUCHERID:filter['voucherId']})
                if fund:
                    alloct = fund[0].getValue(fund[0].COL_MONEY)
                    
                    if len(fund) != 1:
                        print ('Error mul ret val', billId, filter['voucherId'])
            
            if (filter.has_key('show') and filter['show'] == 'alloct'):
                if alloct <= 0.0:
                    continue
                        
            dataRow.append(billId)
            dataRow.append(bill.getValue(bill.COL_TOTAL))
            #print(bill.getValue(bill.COL_TOTAL))
            dataRow.append(bill.getValue(bill.COL_DISCOUNT))
            
            # 增加其他付款单的分配情况
            alloctExtra = bill.getValue(bill.COL_TOTAL)-bill.getValue(bill.COL_DISCOUNT)-bill.getUnpaid()-alloct
            dataRow.append(alloctExtra)
            
            dataRow.append(alloct)
            dataRow.append(bill.getUnpaid())

            if(self.ClsPeer == CDataCustomer):
                dataRow.append(bill.getValue(bill.COL_DLVYINFO)) # 配送方式
                dataRow.append(bill.getValue(bill.COL_STATE))
                dataRow.append(bill.getValue(bill.COL_MEMO))
                dataRow.append(CDataStaff.getName(bill.getValue(bill.COL_HANDLERID)))
            
            data.append(dataRow)
             
        return data

    def appendBill(self, billObj):
        '''根据指定订单付款，默认付款金额为该订单欠款金额'''
        row = self.InsertStringItem(sys.maxint, '')
            
        self.SetStringItem(row, self.iBillId, billObj.getValue(billObj.COL_ID))
        self.SetStringItem(row, self.iTotal, str(billObj.getValue(billObj.COL_TOTAL))) 
        #self.SetStringItem(row, self.iPaid, str(billObj.getPaid()))
        self.SetStringItem(row, self.iDiscount, str(billObj.getValue(billObj.COL_DISCOUNT)))
        self.SetStringItem(row, self.iAlloct, str(billObj.getUnpaid()))
        self.SetStringItem(row, self.iUnpaid, str(billObj.getUnpaid())) 
        
        #alloctExtra = billObj.getValue(billObj.COL_TOTAL)-billObj.getValue(billObj.COL_DISCOUNT)-billObj.getUnpaid()-alloct
        self.SetStringItem(row, self.iAlloctExtra, str(billObj.getPaid())) 

        if(self.ClsPeer == CDataCustomer):
            bill = billObj
            self.SetStringItem(row, self.iDlvy, bill.getValue(bill.COL_DLVYINFO)) # 配送方式
            self.SetStringItem(row, self.iState, bill.getValue(bill.COL_STATE))
            self.SetStringItem(row, self.iMemo, bill.getValue(bill.COL_MEMO))
            self.SetStringItem(row, self.iHandler, CDataStaff.getName(bill.getValue(bill.COL_HANDLERID)))
     
        print(str(billObj.getValue(billObj.COL_TOTAL)), billObj.getValue(billObj.COL_TOTAL))

    def getOrderId(self, row):
        return self.GetItem(row, self.iBillId).GetText()
                   
    def getAlloctSum(self):
        amount = 0.0
        for row in range(self.GetItemCount()):
            val = self.GetItem(row, self.iAlloct).GetText()
            if (val != ''):
                amount += float(val)
        return amount
    
    def resetUnpaid(self, row):
        unpaid = float(self.GetItem(row, self.iTotal).GetText())\
                    - float(self.GetItem(row, self.iAlloct).GetText()) \
                    - float(self.GetItem(row, self.iAlloctExtra).GetText())\
                    - float(self.GetItem(row, self.iDiscount).GetText())

        self.SetStringItem(row, self.iUnpaid, str(unpaid if abs(unpaid)>0.01 else "0"))
        
    def attachVoucher(self, voucherObj):
        bills = voucherObj.getAllocateInfo()        
        for billId,money in bills:
            for row in range(self.GetItemCount()):
                if (billId == self.GetItem(row, self.iBillId).GetText()):
                    self.SetStringItem(row, self.iAlloct, str(money))
                    # 修改paid
                    #paid = float(self.GetItem(row, self.iPaid).GetText()) - money
                    #self.SetStringItem(row, self.iPaid, str(paid))
                    # 修改unpaid
                    self.resetUnpaid(row)
    
    def autoAlloct(self, money):
        for row in range(self.GetItemCount()):
            unpaid = float(self.GetItem(row, self.iUnpaid).GetText())
            #if (unpaid <= 0.0):
            if (abs(unpaid) < 0.01):
                continue
            
            alloct = float(self.GetItem(row, self.iAlloct).GetText())
            if (alloct + money <= unpaid):
                self.setAlloct(row, alloct + money)
                break
            else:
                money = money - unpaid + alloct
                self.setAlloct(row, unpaid)
                        
    def clearAlloct(self):
        for row in range(self.GetItemCount()):
            self.setAlloct(row, 0.0)
           
    def getAlloct(self, row):
        return float(self.GetItem(row, self.iAlloct).GetText())
         
    def setAlloct(self, row, val):
        self.SetStringItem(row, self.iAlloct, str(val))
        #paid = float(self.GetItem(row, self.iPaid).GetText()) + val
        #unpaid = float(self.GetItem(row, self.iUnpaid).GetText()) - val
        #self.SetStringItem(row, self.iPaid, str(paid))
        #self.SetStringItem(row, self.iUnpaid, str(unpaid))
        self.resetUnpaid(row)
        
        self.refreshStatBar()
    
    def setDiscount(self, row, val):
        self.SetStringItem(row, self.iDiscount, str(val))
        #unpaid = float(self.GetItem(row, self.iUnpaid).GetText()) - val
        self.resetUnpaid(row)
        self.refreshStatBar()

class MyOrderListCtrl(MySortListCtrl):
    '''显示订单列表'''

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    xlsFile = u'销售单列表.xlsx'
    
##    def __init__(self, parent):
##        self.cols = []
##       
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
##        
##        #右键菜单
##        #self.initMenu()
##        
##        #self.initStatBar()
    
    def makeCols(self):
        self.iBillId = self.appendCol((u'订单号', wx.LIST_FORMAT_LEFT, 165))
        self.iDate = self.appendCol((u'订单日期', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 120))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT,  70))
        self.iPaid = self.appendCol((u'已付', wx.LIST_FORMAT_RIGHT,  70))
        self.iDiscount = self.appendCol((u'优惠', wx.LIST_FORMAT_RIGHT, 70))
        self.iUnpaid = self.appendCol((u'未付', wx.LIST_FORMAT_RIGHT,  70))        
        self.iState = self.appendCol((u'状态', wx.LIST_FORMAT_LEFT,  60))
        self.iDlvy = self.appendCol((u'配送方式', wx.LIST_FORMAT_LEFT,  -1))
        self.iMemo = self.appendCol((u'备注信息', wx.LIST_FORMAT_LEFT,  -1))
        self.iDlvyPlan = self.appendCol((u'直送单', wx.LIST_FORMAT_LEFT,  -1))
        self.iIsPrinted = self.appendCol((u'印', wx.LIST_FORMAT_LEFT,  30))
        self.iWechat = self.appendCol((u'微', wx.LIST_FORMAT_LEFT,  30))
        self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT,  -1))
        self.iRecorder = self.appendCol((u'操作员', wx.LIST_FORMAT_LEFT, -1))
        self.iPeerId = self.appendCol((u'客户ID', wx.LIST_FORMAT_LEFT, 0))
    
        self.m_only_show_unpaid = False
        self.m_only_show_not_delivery = False
        
    def SetShowMode(self, only_show_unpaid, only_show_not_delivery):
        self.m_only_show_unpaid = only_show_unpaid
        self.m_only_show_not_delivery = only_show_not_delivery
        
    
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':,'peerName':,'dateStart':, 'dateEnd':}
        '''

        return CDataSaleOrder.queryOrders(filter['dateStart']
            , filter['dateEnd']
            , filter['peerId'] if filter.has_key('peerId') else None
            , filter['pioneerId'] if filter.has_key('pioneerId') else None
            , self.m_only_show_unpaid
            #, self.m_only_show_not_delivery
            , filter['show'])

        filterSql = ''
        data = []
            
        if (filter.has_key('dateStart')):
            filterSql += "billDate between '%s' and '%s'" \
                            %(filter['dateStart'], filter['dateEnd'])
        if (filter.has_key('peerId')):
            filterSql += ' and peerId=%d' %filter['peerId']
            
        saleOrderListRef = CDataSaleOrder.fetch(filterSql)
        if (saleOrderListRef is None):
            return 0
            
        for saleOrder in (saleOrderListRef):
            dataRow = []
            dataRow.append(saleOrder.getFieldVal('id'))
            if (filter.has_key('peerId')):
                dataRow.append(filter['peerName'])
            else:
                cust = CDataCustomer.getData({'id':saleOrder.getFieldVal('peerId')})
                if cust is None:
                    print 'Error:None cust %d' %saleOrder.getFieldVal('peerId')
                    dataRow.append('None')
                else:
                    dataRow.append(cust.getFieldVal('name'))

                if (filter.has_key('pioneerId')):
                    if (cust.getFieldVal('pioneer') != filter['pioneerId']):
                        continue
            
            #dataRow.append(saleOrder.getFieldVal('paid'))
            #dataRow.append(saleOrder.getFieldVal('unpaid'))
            paid = CRelFundCustomer.getPaidAmount(saleOrder.getValue(CDataSaleOrder.COL_ID))
            total = saleOrder.getFieldVal('total')
            discount = saleOrder.getFieldVal('discount')
            unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
            dataRow.append(total)
            dataRow.append(paid)
            dataRow.append(discount)
            dataRow.append(unpaid)
            if (self.m_only_show_unpaid and abs(unpaid) < 0.001):
                continue
            
            dataRow.append(saleOrder.getFieldVal('billDate'))
            dataRow.append(saleOrder.getValue(saleOrder.COL_STATE))
            dataRow.append(saleOrder.getDlvyAddr())
##            dlvyId = saleOrder.getFieldVal('dlvyId')
##            if (dlvyId is None):
##                dataRow.append('')
##            else:
##                dataRow.append(
##                    CDataDelivery.getFirstFieldVal({'id':dlvyId},'name'))#Get from other table
            dataRow.append(saleOrder.getFieldVal('memo'))
            deliveryPlan = saleOrder.getValue(saleOrder.COL_DELIVERYPLAN)
            if (self.m_only_show_not_delivery and deliveryPlan is not None):
                continue
            
            dataRow.append(deliveryPlan)
            dataRow.append(u'√' if saleOrder.isPrinted() else u'×')
            
            dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_HANDLERID)))
            dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_RECOREDERID)))
            dataRow.append(saleOrder.getValue(saleOrder.COL_PEERID))
          
            data.append(dataRow)
            
        return data
    
        
    def reloadItem(self, item):
        billId = self.getBillId(item)
        obj = CDataSaleOrder.findObj(billId) # 重新读取数据库
        dataList = [u'--'] * len(self.cols)
        
        dataList[self.iBillId] = obj.getFieldVal('id')
        
        peerObj = obj.getPeerObj()
        dataList[self.iPeerName] = peerObj.getFieldVal('name')
    
        paid = CRelFundCustomer.getPaidAmount(dataList[self.iBillId])
        total = obj.getFieldVal('total')
        discount = obj.getFieldVal('discount')
        unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
        dataList[self.iTotal] = total
        dataList[self.iPaid] = paid
        dataList[self.iDiscount] = discount
        dataList[self.iUnpaid] = unpaid
            
        dataList[self.iDate] = obj.getFieldVal('billDate')
        dataList[self.iState] = obj.getValue(obj.COL_STATE)
        dataList[self.iDlvy] = obj.getDlvyAddr()

        dataList[self.iMemo] = obj.getFieldVal('memo')
        dataList[self.iDlvyPlan] = obj.getValue(obj.COL_DELIVERYPLAN)
        dataList[self.iIsPrinted] = '√' if obj.isPrinted() else u'×'
        dataList[self.iHandler] = CDataStaff.getName(obj.getValue(obj.COL_HANDLERID))
        dataList[self.iRecorder] = CDataStaff.getName(obj.getValue(obj.COL_RECOREDERID))
        dataList[self.iPeerId] = obj.getValue(obj.COL_PEERID)
        
        return dataList
            

            
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal,self.iPaid,self.iUnpaid,self.iDiscount])

        self.tStatList[self.iPeerName].SetLabel(u'共%d条记录'  %self.GetItemCount())
##        total = 0
##        paid = 0
##        unpaid = 0
##        discount = 0
##        
##        for row in range(self.GetItemCount()):
##            total += float(self.GetItem(row, 2).GetText())
##            paid += float(self.GetItem(row, 3).GetText())
##            unpaid += float(self.GetItem(row, 4).GetText())
##            discount += float(self.GetItem(row, 5).GetText())
##        
##        self.tStatList[2].SetLabel(str(total))
##        self.tStatList[3].SetLabel(str(paid))
##        self.tStatList[4].SetLabel(str(unpaid))
##        self.tStatList[5].SetLabel(str(discount))
        
        # 初始化时，因为listctrl没有数据，所以statBar的大小有问题，不显示
        # 在刷新出数据时，重设位置
        #self.resetStatPos()
            
    # def initMenu_obsolete(self):
    #     self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)   
              
    #     #右键菜单
    #     self.menu = wx.Menu()
    #     self.menuList = [u'编辑订单', u'新增付款']
    #     [self.MENU_MODIFY, self.MENU_VOUCHER] = [i for i in range(len(self.menuList))]

    #     for text in self.menuList:
    #         item = self.menu.Append(-1, text)
    #         self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
    
    def makeMenu(self):
        
        item = self.menu.Append(-1, u'直接收款')
        self.Bind(wx.EVT_MENU, self.OnMenuVoucherDlg, item) 

        item = self.menu.Append(-1, u'新增付款')
        self.Bind(wx.EVT_MENU, self.OnMenuVoucher, item) 
        
        self.menu.AppendSeparator()
        
        # 二级菜单 - 编辑
        editMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'编辑订单', editMenu)
        
        item = editMenu.Append(-1, u'重新编辑订单')
        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)  
        
        editMenu.AppendSeparator()
        item = editMenu.Append(-1, u'修改订单备注')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyMemo, item) 
        
        item = editMenu.Append(-1, u'修改订单状态')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyState, item) 
        
        item = editMenu.Append(-1, u'修改订单配送')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyDlvy, item) 
        
        self.menu.AppendSeparator()
        
        # 二级菜单 - 打印
        printMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'打印单据', printMenu)
        
        item = printMenu.Append(-1, u'打印单据（含应付总额）')
        self.Bind(wx.EVT_MENU, self.OnMenuPrint, item)  
        
        item = printMenu.Append(-1, u'打印单据（不含应付总额）')
        self.Bind(wx.EVT_MENU, self.OnMenuPrintNoDebt, item)  
        
        item = printMenu.Append(-1, u'打印单据（备注附加对账单）')
        self.Bind(wx.EVT_MENU, self.OnMenuPrintWithFund, item)  

        printMenu.AppendSeparator()

        item = printMenu.Append(-1, u'打印标签')
        self.Bind(wx.EVT_MENU, self.OnMenuPrintTag, item)  
        
        self.menu.AppendSeparator()
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            # 二级菜单 - 删除  主要是为了避免误点击
            delMenu = wx.Menu()
            item = self.menu.AppendMenu(-1, u'删除订单', delMenu)
            
            item = delMenu.Append(-1, u'删除订单')
            self.Bind(wx.EVT_MENU, self.OnMenuDel, item)  
            
            self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
        
        self.menu.AppendSeparator()

        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'利润试核算')
            self.Bind(wx.EVT_MENU, self.OnMenuProfitCalc, item) 
            self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'新增销售单')
        self.Bind(wx.EVT_MENU, self.OnMenuNewOrder, item) 
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'查看图片')
        self.Bind(wx.EVT_MENU, self.OnMenuShowImage, item)

        self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'编辑客户')
        self.Bind(wx.EVT_MENU, self.OnMenuEditCustmor, item) 
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'拷贝欠款账单')
        self.Bind(wx.EVT_MENU, self.OnMenuCopyUnpaid, item) 
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'查询客户')
        self.Bind(wx.EVT_MENU, self.OnMenuSearch, item) 
        
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'添加客情')
        self.Bind(wx.EVT_MENU, self.OnMenuAddLog, item)        

        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'导出订单(指掌格式)')
        self.Bind(wx.EVT_MENU, self.OnMenuExportOrder, item)

        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnMenuPrint) # 双击打印
        
    def OnMenuExportOrder(self, event):
        '''导出指掌格式订单'''

        #if not PermitManager.accessTest(const.PERMIT_EXPORT):
        #    return
        
        dlg = wx.FileDialog(
            self, message="Save file as ..."
            , defaultDir=os.getcwd()
            , defaultFile=u"销售订单批量导入"#"%s"%self.getXlsFileName()
            , wildcard='*.xlsx'
            , style=wx.SAVE
            )
        
        if dlg.ShowModal() != wx.ID_OK:
            return
        
        file = dlg.GetPaths()[0]

        idList = ",".join(["'"+self.getBillId(i)+"'" for i in range(self.GetItemCount())])
        
        if(kit.exportSelect(CDataSaleDetail.ExportOrders(idList), file) < 0):
            msg = u'数据导出失败，请查看是不是其他程序中打开了该文件！'
        else:
            msg = u'数据完成导出'
            
        dlg = wx.MessageDialog(self, msg, u'提示',wx.OK|wx.ICON_INFORMATION)
        dlg.ShowModal()


    def OnMenuCopyUnpaid(self, event):
        import pyperclip
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        cnt = 0
        val = 0.0
        #text = self.GetItem(item, self.iPeerName).GetText() + "\n"
        text = CDataCustomer.getPrintName(self.getPeerId(item)) + "\n"
        for row in range(self.GetItemCount()-1, -1, -1): # 改为倒序
            if (abs(float(self.GetItem(row, self.iUnpaid).GetText())) >= 0.01):
                cnt += 1
                val += float(self.GetItem(row, self.iUnpaid).GetText())
                text += "%s\t%g\n" %(self.GetItem(row, self.iDate).GetText(), \
                    float(self.GetItem(row, self.iUnpaid).GetText()))
        text += u"共%d单，%g元" %(cnt, val)
        pyperclip.copy(text)
    
    def OnMenuDlvyReport(self, event):
        ''' 司机报备 '''
        
        import DlgAddCustomerLog
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        if (self.GetItem(item, self.iDlvyPlan).GetText() == ""):
            dlg = wx.MessageDialog(self, u'不是送货单',u'提示',
                                    wx.OK|wx.ICON_ERROR)
            dlg.ShowModal()
            return
            
        dlg = DlgAddCustomerLog.create(self)
        dlg.setData(self.getPeerId(item),
            self.GetItem(item, self.iDlvyPlan).GetText())
        dlg.ShowModal()
        
    
    def OnMenuAddLog(self, event):
        ''' 添加客情 '''
        import DlgAddCustomerLog
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        dlg = DlgAddCustomerLog.create(self)
        dlg.setData(self.getPeerId(item))
        dlg.ShowModal()
        
    def OnMenuSearch(self, event):
        '''设置客户/供货商到搜索栏，以便进行搜索'''
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        billId = self.getBillId(item)
        billObj = CDataSaleOrder.findObj(billId)
        peerId = billObj.getValue(billObj.COL_PEERID)
        peerObj = CDataCustomer.getData({'id':peerId})#.findObj(peerId)
        self.GetParent().GetParent().search_by_peer(peerObj)#setSelectObj(peerObj)
    
    def OnMenuProfitCalc(self, event):
        import DlgProfit
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = DlgProfit.create(self)
        dlg.setData(self.getBillId(item))
        dlg.ShowModal()
        
    def printOrder(self, printDebt=True, printFund=False):
        import MyPrinter 
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        MyPrinter.MyPrinter.printSaleOrder(self, self.getBillId(item), printDebt, printFund)
        
    def OnMenuPrintNoDebt(self, event):
        self.printOrder(printDebt=False)
        
    def OnMenuPrintWithFund(self, event):
        self.printOrder(printFund=True)
    
    def OnMenuPrint(self, event):
        self.printOrder()

    def OnMenuPrintTag(self, event):

        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        TagPrinter.printTag(kit.getRootWin(self), self.getBillId(item)) 
    
    def OnMenuModifyState(self, event):
        import DlgOrderState
        
        #billObj = self.getObj()
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
 
        billObj = CDataSaleOrder.findObj(self.getBillId(item))
        
        dlg = DlgOrderState.create(self)
        if dlg.ShowModal() == wx.ID_OK:
            billObj.setValue(billObj.COL_STATE, dlg.getSelVal())
            billObj.update()
            self.refreshItem(item)
            
            
    def OnMenuModifyDlvy(self, event):
        import DlgDelivery
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        billId = self.getBillId(item)
        billObj = CDataSaleOrder.findObj(billId)
        peerId = billObj.getValue(billObj.COL_PEERID)
        peerObj = CDataCustomer.getData({'id':peerId})#.findObj(peerId)
        
        dlg = DlgDelivery.create(self)        
        dlg.setPeer(peerObj)
        if dlg.ShowModal() == wx.ID_OK:
            #dlvyObj = dlg.getSelectObj()
            #billObj.setValue(billObj.COL_DLVYID, dlvyObj.getKeyVal())
            #billObj.update()
            billObj.updateDlvyInfo(dlg.getSelectObj())
            self.refreshItem(item)
        
    def OnMenuDel(self, event):
        if not PermitManager.accessTest(const.PERMIT_DEL_ORDER):
            return
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.MessageDialog(self, u'删除后将无法恢复，是否确认删除?',u'提示',
                                wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return
            
        billId = self.getBillId(item)
        CDataSaleOrder.deleteBill(billId)
        #看看是不是会影响效率，订单页面似乎没必要保持显示（会产生同步问题）
        self.reloadData()
    
    def OnMenuModifyMemo(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        billId = self.getBillId(item)
        billObj = CDataSaleOrder.findObj(billId)
        memo = billObj.getValue(billObj.COL_MEMO)
        
        dlg = wx.TextEntryDialog(
                self, u'修改订单备注：',u'修改订单备注：', memo)
        if dlg.ShowModal() == wx.ID_OK:
            billObj.setValue(billObj.COL_MEMO, dlg.GetValue())
            billObj.update()
            self.refreshItem(item)
                
    def OnMenuEdit(self, event):
        if not PermitManager.accessTest(const.PERMIT_MODIFY_ORDER):
            return
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.MessageDialog(self, u'该订单为正式订单，是否修改?',u'提示',wx.YES_NO|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return

        self.getMainFrame().addPageSale(self.getSaleId(item))
            
    def OnMenuVoucher(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        self.getMainFrame().addPageVoucher(self.getBillId(item))
            
    def OnPopupMenu_obsolete(self, event):
        '''商品分类右键弹出菜单处理'''
        print 'OnPopupMenu'

        pos = self.ScreenToClient(event.GetPosition())
        self.PopupMenu(self.menu, pos)

#     def OnPopupMenuSelected_obsolete(self, event):
#         #import FrameSO
#         import PanelOrderSale
#         #import DlgPayment
#         import DlgVoucherStyle
#         import DlgVoucher
        
#         menuItem = self.menu.FindItemById(event.GetId())
#         print menuItem.GetText()
        
#         if (menuItem.GetText() == self.menuList[self.MENU_MODIFY]):
#             item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
#             if (item == -1):
#                 return
            
#             dlg = wx.MessageDialog(self, u'该订单为正式订单，是否修改?',u'提示',wx.YES_NO|wx.ICON_QUESTION)
#             if(dlg.ShowModal() == wx.ID_NO):
#                 return

#             #dlg = FrameSO.create(self.getMainFrame())
#             #dlg.setData(self.getSaleId(item))
#             #dlg.Show()
#             self.getMainFrame().addPageSale(self.getSaleId(item))
            
#         elif (menuItem.GetText() == self.menuList[self.MENU_VOUCHER]):
#             item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
#             if (item == -1):
#                 return
            
#             #dlg = DlgPayment.create(self)
#             #dlg.setData(self.getSaleId(item))
#             #dlg.ShowModal()
            
# ##            unpaid = float(self.GetItem(item, 4).GetText())
# ##            if(unpaid <= 0.0):
# ##                bPayForBill = False
# ##            else:
# ##                dlg = DlgVoucherStyle.create(self)
# ##                dlg.ShowModal()
# ##                bPayForBill = dlg.payForBill()
# ##                
# ##            if(bPayForBill):
# ##                dlg = DlgVoucher.DlgVoucher(self, DlgVoucher.Type_Customer)
# ##                dlg.ShowModal()
# ##            else:
# ##                billId = self.getBillId(item)
# ##                billObj = CDataSaleOrder.getFirstInstance({CDataSaleOrder.COL_ID:billId})
# ##                peerId = billObj.getValue(billObj.COL_PEERID)
# ##                peerObj = CDataCustomer.getFirstInstance({CDataCustomer.COL_ID:peerId})
# ##                self.getMainFrame().addPageVoucher(peerObj)
            
# ##            unpaid = float(self.GetItem(item, 4).GetText())
# ##            if(unpaid <= 0.0):
# ##                self.getMainFrame().addPageVoucher(peerObj)
# ##            else:
# ##                self.getMainFrame().addPageVoucher(peerObj, self.getBillId(item))
            
#             self.getMainFrame().addPageVoucher(self.getBillId(item))

    def getMainFrame(self):
        #return self.GetParent().GetParent()
        win = self
        while(win.GetParent()):
            win = win.GetParent()
        return win
    
##    def refresh(self, filter={}):
##        self.curFilter = filter
##        self.listAll = True
##        
##        self.DeleteAllItems() 
##        self.itemDataMap = {}
##  
##        filterSql = ''
##            
##        if (filter.has_key('dateStart')):
##            filterSql += "billDate between '%s' and '%s'" \
##                            %(filter['dateStart'], filter['dateEnd'])
##        if (filter.has_key('peerId')):
##            filterSql += ' and peerId=%d' %filter['peerId']
##            
##        saleOrderListRef = CDataSaleOrder.fetch(filterSql)
##        if (saleOrderListRef is None):
##            return 0
##        dlg = wx.MessageDialog(self, u'该订单为正式订单，是否修改?',u'提示',wx.OK|wx.ICON_QUESTION)
##        dlg.ShowModal()
##        for saleOrder in (saleOrderListRef):
##            dataRow = []
##            dataRow.append(saleOrder.getFieldVal('id'))
##            if (filter.has_key('peerId')):
##                dataRow.append(filter['peerName'])
##            else:
##                cust = CDataCustomer.getData({'id':saleOrder.getFieldVal('peerId')})
##                if cust is None:
##                    print 'Error:None cust %d' %saleOrder.getFieldVal('peerId')
##                    dataRow.append('None')
##                else:
##                    dataRow.append(cust.getFieldVal('name'))
##            
##            
##            #dataRow.append(saleOrder.getFieldVal('paid'))
##            #dataRow.append(saleOrder.getFieldVal('unpaid'))
##            paid = CRelFundCustomer.getPaidAmount(saleOrder.getValue(CDataSaleOrder.COL_ID))
##            total = saleOrder.getFieldVal('total')
##            discount = saleOrder.getFieldVal('discount')
##            unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
##            dataRow.append(total)
##            dataRow.append(paid)
##            dataRow.append(unpaid)
##            dataRow.append(discount)
##            
##            dataRow.append(saleOrder.getFieldVal('billDate'))
##            dataRow.append(saleOrder.getValue(saleOrder.COL_STATE))
##            dataRow.append(saleOrder.getFieldVal('dlvyAddr'))
####            dlvyId = saleOrder.getFieldVal('dlvyId')
####            if (dlvyId is None):
####                dataRow.append('')
####            else:
####                dataRow.append(
####                    CDataDelivery.getFirstFieldVal({'id':dlvyId},'name'))#Get from other table
##            dataRow.append(saleOrder.getFieldVal('memo'))
##            dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_HANDLERID)))
##            dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_RECOREDERID)))
##          
##            
##        
##            row = self.InsertStringItem(sys.maxint, '')
##            #if (index != row):
##            #    raise Exception()
##            for col in range(len(dataRow)):
##                val = dataRow[col]
##                if (val == None):
##                    val = ''
##                if (type(val) != str and type(val) != unicode):
##                    val = str(val)
##                
##                self.SetStringItem(row, col, val)   
##            
##            self.Update()
##            
##            self.SetItemData(row, row)
##            #虽然data是局部变量，但是python是垃圾自动回收，由于该数据有引用，
##            #所以根据一般原理，该数据区域不会被回收
##            #如果出现问题，可以使用self.data，不过为了验证设想，使用局部变量
##            self.itemDataMap[row]=dataRow
##        
##        self.refreshBgColour()
##        
##        # 140815
##        if (self.include_statBar):
##            self.refreshStatBar()
####            self.resetStatValue()
####            # 初始化时，因为listctrl没有数据，所以statBar的大小有问题，不显示
####            # 在刷新出数据时，重设位置
####            self.resetStatPos()
##        
##        #self.resizeClient() # 无 效
##        return
    
    def getSaleId(self, item):
        return self.GetItem(item, 0).GetText()
    
    def getBillId(self, item):
        return self.GetItem(item, 0).GetText()
    
    def getPeerId(self, item):
        return int(self.GetItem(item, self.iPeerId).GetText())
        
    def getObj(self, item=-1):
        '''
            获取相关对象，默认为选中项
        
            item - 默认-1为选中项
        ''' 
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return None
 
        return CDataSaleOrder.findObj(self.getBillId(item))
        
class MyListCtrlPurOrder(MySortListCtrl):
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    xlsFile = u'采购单列表.xlsx'
    
##    def __init__(self, parent):
##        self.cols = [(u'订单号', wx.LIST_FORMAT_LEFT, 160),
##                    (u'供货商名称', wx.LIST_FORMAT_LEFT, 120),
##                    (u'总金额', wx.LIST_FORMAT_RIGHT,  -1), 
##                    (u'已付金额', wx.LIST_FORMAT_RIGHT,  -1), 
##                    (u'未付金额', wx.LIST_FORMAT_RIGHT,  -1), 
##                    (u'优惠金额', wx.LIST_FORMAT_RIGHT, -1), 
##                    (u'订单日期', wx.LIST_FORMAT_LEFT,  90), 
##                    (u'备注', wx.LIST_FORMAT_LEFT,  -1), 
##                    (u'经手人', wx.LIST_FORMAT_LEFT,  -1),
##                    (u'操作员', wx.LIST_FORMAT_LEFT, -1)]
##       
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
    
        # 右键菜单
        #self.initMenu()
        
        # bottom stat line
        #self.initStatBar()

    def makeCols(self):
        self.iBillId = self.appendCol((u'订单号', wx.LIST_FORMAT_LEFT, 180))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 120))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT,  -1)) 
        self.iPaid = self.appendCol((u'已付金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iUnpaid = self.appendCol((u'未付金额', wx.LIST_FORMAT_RIGHT,  -1))
        self.iDiscount = self.appendCol((u'优惠金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iDate = self.appendCol((u'订单日期', wx.LIST_FORMAT_LEFT,  0))
        self.iWh = self.appendCol((u'入库', wx.LIST_FORMAT_LEFT,  50))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT,  150))
        self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT,  60))
        self.iRecorder = self.appendCol((u'操作员', wx.LIST_FORMAT_LEFT, 60))
        
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal,self.iPaid,self.iUnpaid,self.iDiscount])
            
##    def resetStatPos(self):
##        itemHeight = self.GetItemRect(0).GetHeight()
##        
##        posX = 0
##        posY = self.GetClientSize().GetHeight() - itemHeight
##        for i in range(len(self.cols)):
##            self.tStatList[i].Move((posX, posY))
##            self.tStatList[i].SetSize(wx.Size(self.GetColumnWidth(i)-1, itemHeight))
##            posX += self.GetColumnWidth(i)
    
##    def resetStatValue(self):
##        total = 0
##        paid = 0
##        unpaid = 0
##        discount = 0
##        
##        for row in range(self.GetItemCount()):
##            total += float(self.GetItem(row, 2).GetText())
##            paid += float(self.GetItem(row, 3).GetText())
##            unpaid += float(self.GetItem(row, 4).GetText())
##            discount += float(self.GetItem(row, 5).GetText())
##        
##        self.tStatList[2].SetLabel(str(total))
##        self.tStatList[3].SetLabel(str(paid))
##        self.tStatList[4].SetLabel(str(unpaid))
##        self.tStatList[5].SetLabel(str(discount))
        
        #self.resetStatPos()
        
##    def initStatBar(self):
##        self.Bind(wx.EVT_LIST_COL_END_DRAG, self.OnListColEndDrag)
##              
##        self.tStatList = []
##        for i in range(len(self.cols)):
##            txt = wx.StaticText(self, -1, "", style=wx.ALIGN_RIGHT)
##            txt.SetBackgroundColour(wx.Colour(0, 255, 255))
##            self.tStatList.append(txt)
        
        
    def makeMenu(self):
        
        item = self.menu.Append(-1, u'新增付款')
        self.Bind(wx.EVT_MENU, self.OnMenuPay, item) 
        
        self.menu.AppendSeparator()
		
        item = self.menu.Append(-1, u'编辑订单')
        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)  

        self.menu.AppendSeparator()
        item = self.menu.Append(-1, u'修改订单备注')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyMemo, item) 
        
        self.menu.AppendSeparator()            
        
        MySortListCtrl.appendCommonMenu(self)

        self.menu.AppendSeparator()
        item = self.menu.Append(-1, u'导出订单(指掌格式)')
        self.Bind(wx.EVT_MENU, self.OnMenuExportOrder, item)  


    def OnMenuExportOrder(self, event):
        '''导出指掌格式订单'''

        #if not PermitManager.accessTest(const.PERMIT_EXPORT):
        #    return
        
        dlg = wx.FileDialog(
            self, message="Save file as ..."
            , defaultDir=os.getcwd()
            , defaultFile=u"采购入库单批量导入" #"%s"%self.getXlsFileName()
            , wildcard='*.xlsx'
            , style=wx.SAVE
            )
        
        if dlg.ShowModal() != wx.ID_OK:
            return
        
        file = dlg.GetPaths()[0]

        idList = ",".join(["'"+self.getBillId(i)+"'" for i in range(self.GetItemCount())])
        
        if(kit.exportSelect(CDataPurDetail.ExportOrders(idList), file, False) < 0):
            msg = u'数据导出失败，请查看是不是其他程序中打开了该文件！'
        else:
            msg = u'数据完成导出'
            
        dlg = wx.MessageDialog(self, msg, u'提示',wx.OK|wx.ICON_INFORMATION)
        dlg.ShowModal()


    def OnMenuModifyMemo(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        billId = self.getBillId(item)
        billObj = CDataPurOrder.findObj(billId)
        memo = billObj.getValue(billObj.COL_MEMO)   
        dlg = wx.TextEntryDialog(
                self, u'修改订单备注：',u'修改订单备注：', memo)
        if dlg.ShowModal() == wx.ID_OK:
            billObj.setValue(billObj.COL_MEMO, dlg.GetValue())
            billObj.update()
            self.refreshItem(item)
        

            
##    def initMenu(self):
##        self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)
##        
##        self.menu = wx.Menu()
##        
##        item = self.menu.Append(-1, u'编辑订单')
##        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)   
##              
##        item = self.menu.Append(-1, u'新增付款')
##        self.Bind(wx.EVT_MENU, self.OnMenuPay, item)
##    
##    def OnPopupMenu(self, event):
##        '''商品分类右键弹出菜单处理'''
##        print 'OnPopupMenu'
##
##        pos = self.ScreenToClient(event.GetPosition())
##        self.PopupMenu(self.menu, pos)
    
    def getMainFrame(self):
        #return self.GetParent().GetParent()
        win = self
        while(win.GetParent()):
            win = win.GetParent()
        return win
    
    def OnMenuEdit(self, event):
        #import FramePurOrder
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        dlg = wx.MessageDialog(self, u'该订单为正式订单，是否修改?',u'提示',wx.YES_NO|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return
        self.getMainFrame().addPagePurchase(self.getBillId(item))
        
        #dlg = FramePurOrder.create(self.getMainFrame())
        #dlg.setEditBill(self.getBillId(item))
        #dlg.Show()
        
    
    def OnMenuPay(self, event):
        #import DlgVoucher
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        #dlg = DlgVoucher.DlgVoucher(self, DlgVoucher.Type_Supplier)
        #dlg.setData(self.getBillId(item))
        #dlg.ShowModal()
        self.getMainFrame().addPagePayment(self.getBillId(item))
    
    def getBillId(self, item):
        return self.GetItem(item, 0).GetText()
    
    def getPeerId(self, item):
        return self.GetItem(item, 0).GetText()

    def refreshBgColour(self):
        for row in range(self.GetItemCount()):            
            if (self.GetItem(row, self.iWh).GetText() == ""):
                self.SetItemBackgroundColour(row, wx.Colour(250, 166, 140))
            else:
                self.resetBgcolour(row)

    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':,'dateStart':, 'dateEnd':}
        '''
        filterSql = ''
        data = []
            
        if (filter.has_key('dateStart')):
            filterSql += "billDate between '%s' and '%s'" \
                            %(filter['dateStart'], filter['dateEnd'])
        if (filter.has_key('peerId')):
            filterSql += ' and peerId=%d' %filter['peerId']
            
        billList = CDataPurOrder.fetch(filterSql)
        if (billList is None):
            return 0
        
        for bill in (billList):
            dataRow = []
            dataRow.append(bill.getValue(CDataPurOrder.COL_ID))
            if (filter.has_key('peerId')):
                peerId = filter['peerId']
            else:
                peerId = bill.getValue(CDataPurOrder.COL_PEERID)
            
            #dataRow.append(CDataSupplier.findItemValue({CDataSupplier.COL_ID:peerId}, CDataSupplier.COL_NAME))
            peerObj = CDataSupplier.getData({"id":peerId})
            dataRow.append(peerObj.getValue(peerObj.COL_NAME))
            
            # 影响效率
            #paid = CRelFundSupplier.getPaidAmount(bill.getValue(CDataPurOrder.COL_ID))
            total = bill.getValue(CDataPurOrder.COL_TOTAL)
            discount = bill.getValue(CDataPurOrder.COL_DISCOUNT)
            #unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
            dataRow.append(total)
            #dataRow.append(paid)
            #dataRow.append(unpaid)
            dataRow.append(bill.getPaid())
            dataRow.append(bill.getUnpaid())
            dataRow.append(discount)
            
            dataRow.append(bill.getValue(CDataPurOrder.COL_BILLDATE))
            dataRow.append(bill.getValue(CDataPurOrder.COL_WH_IN))
            dataRow.append(bill.getValue(CDataPurOrder.COL_MEMO))
            
            
            dataRow.append(CDataStaff.getName(bill.getValue(CDataPurOrder.COL_HANDLERID)))
            dataRow.append(CDataStaff.getName(bill.getValue(CDataPurOrder.COL_RECOREDERID)))
          
            data.append(dataRow)
            
        return data
    

    def reloadItem(self, item):
        billId = self.getBillId(item)
        bill = CDataPurOrder.findObj(billId) # 重新读取数据库
        dataRow = []
        
        dataRow.append(bill.getValue(CDataPurOrder.COL_ID))
        peerId = bill.getValue(CDataPurOrder.COL_PEERID)
        
        #dataRow.append(CDataSupplier.findItemValue({CDataSupplier.COL_ID:peerId}, CDataSupplier.COL_NAME))
        peerObj = CDataSupplier.getData({"id":peerId})
        dataRow.append(peerObj.getValue(peerObj.COL_NAME))
        
        # 影响效率
        #paid = CRelFundSupplier.getPaidAmount(bill.getValue(CDataPurOrder.COL_ID))
        total = bill.getValue(CDataPurOrder.COL_TOTAL)
        discount = bill.getValue(CDataPurOrder.COL_DISCOUNT)
        #unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
        dataRow.append(total)
        #dataRow.append(paid)
        #dataRow.append(unpaid)
        dataRow.append(bill.getPaid())
        dataRow.append(bill.getUnpaid())
        dataRow.append(discount)
        
        dataRow.append(bill.getValue(CDataPurOrder.COL_BILLDATE))
        dataRow.append(bill.getValue(CDataPurOrder.COL_WH_IN))
        dataRow.append(bill.getValue(CDataPurOrder.COL_MEMO))
        
        
        dataRow.append(CDataStaff.getName(bill.getValue(CDataPurOrder.COL_HANDLERID)))
        dataRow.append(CDataStaff.getName(bill.getValue(CDataPurOrder.COL_RECOREDERID)))
        
        return dataRow

class MyFundCustmoerListCtrl(MySortListCtrl):
    '''显示客户账务信息'''

    [Type_Customer, Type_Supplier] = [i for i in range(2)]
    
    
    def __init__(self, parent, type=Type_Customer):
        self.billType = [u'销售订单', u'付款单据', u'期初欠款']
        [self.BILL_SALE, self.BILL_VOUCHER, self.BILL_INITDEBT] =\
            [i for i in range(len(self.billType))]
            
        self.type = type
        if(self.type == self.Type_Customer):
            self.ClsPeer = CDataCustomer
            self.ClsOrder = CDataSaleOrder
            self.ClsVoucher = CDataVoucher
            self.peerHeader = u'客户名称'
            
        elif(self.type == self.Type_Supplier):
            self.ClsPeer = CDataSupplier
            self.ClsOrder = CDataPurOrder
            self.ClsVoucher = CDataVoucherSupplier
            self.peerHeader = u'供货商名称'
            
            self.billType[self.BILL_SALE] = u'采购订单'
        
        MySortListCtrl.__init__(self, parent, 
                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)
 
    def makeCols(self):
        self.iPeer = self.appendCol((self.peerHeader, wx.LIST_FORMAT_LEFT, 120))
        self.iBillId = self.appendCol((u'单据号', wx.LIST_FORMAT_LEFT, Width_BillId))
        self.iBillType = self.appendCol((u'单据类型', wx.LIST_FORMAT_LEFT, -1))
        self.iAccount = self.appendCol((u'账户', wx.LIST_FORMAT_RIGHT, -1))
        self.iAmount = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iDiscount = self.appendCol((u'优惠金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iYingfu = self.appendCol((u'应付金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iPaid = self.appendCol((u'已付金额', wx.LIST_FORMAT_RIGHT, -1))
        self.iRemain = self.appendCol((u'迄今余额', wx.LIST_FORMAT_RIGHT, -1))
        self.iDate = self.appendCol((u'订单日期', wx.LIST_FORMAT_LEFT, Width_Date))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 200))
            
    # def initMenu_obsolete(self):
    #     self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)   
              
    #     #右键菜单
    #     self.menu = wx.Menu()
    #     self.menuList = [u'查看该客户所有单据', u'编辑单据', u'新增付款',u'删除单据']
    #     [self.MENU_CUST, self.MENU_MODIFY,self.MENU_PAY, self.MENU_DEL] = \
    #         [i for i in range(len(self.menuList))]

    #     for text in self.menuList:
    #         item = self.menu.Append(-1, text)
    #         self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
    
    include_menu = True
    def makeMenu(self):
        #item = self.menu.Append(-1, u'查看该客户所有单据')
        #self.Bind(wx.EVT_MENU, self.OnMenuSelectPeer, item)
        # 
        item = self.menu.Append(-1, u'归结账目')
        self.Bind(wx.EVT_MENU, self.OnMenuSettle, item)   
        
        self.menu.AppendSeparator()
              
        item = self.menu.Append(-1, u'编辑单据')
        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)
        
        self.menu.AppendSeparator()
        
        #item = self.menu.Append(-1, u'直接收款')
        #self.Bind(wx.EVT_MENU, self.OnMenuVoucherDlg, item) 

        item = self.menu.Append(-1, u'新增付款')
        self.Bind(wx.EVT_MENU, self.OnMenuVoucher, item)  
        
        self.menu.AppendSeparator()
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'删除单据')
            self.Bind(wx.EVT_MENU, self.OnMenuDel, item)  
        
            self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)

    def OnMenuSettle(self, event):
        '''结算账目，当前订单日期设置为 上期结算日期，当前余额 设置为 上期期末'''
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        settleDate = self.GetItem(item, self.iDate).GetText()
        preArrears = self.GetItem(item, self.iRemain).GetText()
        dlg = wx.TextEntryDialog(self, u'结算本期账目到该订单，结算后上期期末余额为：', u'结算本期', preArrears)
        if (dlg.ShowModal() == wx.ID_OK):
            #保存修改
            preArrears = float(dlg.GetValue())
            peerObj = self.getPeerObj(item)
            #peerObj.DoSettle(settleDate, preArrears)
            peerObj.setValue(peerObj.COL_PRE_ARREARS, preArrears)
            peerObj.setValue(peerObj.COL_SETTLE_DATE, settleDate)
            peerObj.UpdateSettleInfo()
            self.refreshParent()


    def OnMenuSelectPeer(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        peerObj = self.getPeerObj(item)
        #custId = custObj.getValue(CDataCustomer.COL_ID)
        self.GetParent().setSelectObj(peerObj)
        self.refreshParent()
        
    def refreshBgColour(self):
        for row in range(self.GetItemCount()):
            billType = self.getBillType(row)
            if (billType == self.billType[self.BILL_VOUCHER]):
                self.SetItemBackgroundColour(row, wx.Colour(128, 255, 128))
            else:
                self.SetItemBackgroundColour(row, wx.Colour(164, 242, 189))
            
    def OnMenuEdit(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
    
        billType = self.getBillType(item)
        if (billType == self.billType[self.BILL_SALE]):
            #modify sale order
            dlg = wx.MessageDialog(self, u'该订单为正式订单，是否修改?',u'提示',wx.YES_NO|wx.ICON_QUESTION)
            if(dlg.ShowModal() == wx.ID_NO):
                return
                    
            if(self.type == self.Type_Customer):
                self.getMainFrame().addPageSale(self.getBillId(item))
        
            elif(self.type == self.Type_Supplier):
                self.getMainFrame().addPagePurchase(self.getBillId(item))
      
        elif (billType == self.billType[self.BILL_VOUCHER]):
            #modify voucher
            msg = u'该订单为正式单据，是否修改?\n'\
                    u'注意：修改将解除资金明细的关联，需重新添加\n\n'\
                    u'如果要求改进设计，请致意开发者。'
            dlg = wx.MessageDialog(self, msg,u'提示',wx.YES_NO|wx.ICON_QUESTION)
            if(dlg.ShowModal() == wx.ID_NO):
                return
            
            if(self.type == self.Type_Customer):
                self.getMainFrame().addPageVoucherEditor(self.getBillId(item))
            elif(self.type == self.Type_Supplier):    
                self.getMainFrame().addPagePaymentEditor(self.getBillId(item))
                    
        elif (billType == self.billType[self.BILL_INITDEBT]):
            #modify initDebt
            custName = self.GetItem(item, self.iPeer).GetText()
            msg = u'重设<%s>的期初欠款：' %(custName)
            caption = u'修改客户期初欠款'
            val = self.GetItem(item, self.iAmount).GetText()
            
            dlg = wx.TextEntryDialog(self, msg, caption, val)
            if (dlg.ShowModal() == wx.ID_OK):
                val = dlg.GetValue()
                peerObj = self.getPeerObj(item)
                peerObj.setValue(peerObj.COL_DEBT, float(val))
                peerObj.update()
                self.refreshParent()
                
        else:
            print 'Error billType: %s' %billType
                
    def OnMenuVoucher(self, event):
        # Add voucher        
        import DlgVoucher
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
   
##        if(self.type == self.Type_Customer):
##            dlg = DlgVoucher.DlgVoucher(self, DlgVoucher.Type_Customer)
##        elif(self.type == self.Type_Supplier):
##            dlg = DlgVoucher.DlgVoucher(self, DlgVoucher.Type_Supplier)
##        
##        billId = self.getBillId(item)
##        peerObj = self.getPeerObj(item)
##        dlg.setData(billId, peerObj)
##        
##        if(dlg.ShowModal() == wx.ID_OK):
##            self.refreshParent()
        if(self.getBillId(item) == ''):
            if(self.type == self.Type_Customer):
                self.getMainFrame().addPageVoucher(peerObj=self.getPeerObj(item))
            elif(self.type == self.Type_Supplier):    
                self.getMainFrame().addPagePayment(peerObj=self.getPeerObj(item))
        else:
            if(self.type == self.Type_Customer):
                self.getMainFrame().addPageVoucher(billId=self.getBillId(item))
            elif(self.type == self.Type_Supplier):    
                self.getMainFrame().addPagePayment(billId=self.getBillId(item))
            
    def OnMenuDel(self, event):
        # delete cur bill
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        if (self.getBillType(item) == self.billType[self.BILL_VOUCHER]):
            ClsBill = self.ClsVoucher
        elif(self.getBillType(item) == self.billType[self.BILL_SALE]):
            ClsBill = self.ClsOrder
        else:
            msg = u'不能删除期初欠款，请在菜单<编辑订单>中修改期初欠款金额'
            dlg = wx.MessageDialog(self, msg, u'提示消息', wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal()
            return
            
        msg = u'删除后将无法恢复,确认删除?'
        dlg = wx.MessageDialog(self, msg, u'提示消息', wx.YES_NO|wx.ICON_INFORMATION)
        if(dlg.ShowModal() == wx.ID_YES):
            voucherId = self.getBillId(item)
            voucherObj = ClsBill.getFirstInstance({ClsBill.COL_ID:voucherId})
            voucherObj.deepDelete()
            self.refreshParent()
    
    def OnPopupMenu(self, event):
        '''商品分类右键弹出菜单处理'''
        print 'OnPopupMenu'

        pos = self.ScreenToClient(event.GetPosition())
        self.PopupMenu(self.menu, pos)
                
    # def OnPopupMenuSelected(self, event):
    #     import FrameSO
    #     import DlgPayment
        
    #     item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
    #     if (item == -1):
    #         return
            
    #     menuItem = self.menu.FindItemById(event.GetId())
    #     print menuItem.GetText()
        
    #     if (menuItem.GetText() == self.menuList[self.MENU_MODIFY]):
    #         billType = self.getBillType(item)
    #         if (billType == self.billType[self.BILL_SALE]):
    #             #modify sale order
    #             dlg = FrameSO.create(self.getMainFrame())
    #             dlg.setData(self.getBillId(item))
    #             #MakeModal() canbe used to show modal,but maybe not flexible
    #             #if(dlg.ShowModal() == wx.ID_OK):
    #             #    self.refresh()
    #             dlg.Show()
    #             self.refreshParent()
                
    #         elif (billType == self.billType[self.BILL_VOUCHER]):
    #             #modify voucher
    #             dlg = DlgPayment.create(self.getMainFrame())
    #             voucherId = self.getBillId(item)
    #             voucherObj = CDataVoucher.getFirstInstance({CDataVoucher.COL_ID:voucherId})
    #             saleId = voucherObj.getSaleId()
    #             dlg.setData(saleId, voucherId)
    #             if(dlg.ShowModal() == wx.ID_OK):
    #                 self.refreshParent()
                    
    #         elif (billType == self.billType[self.BILL_INITDEBT]):
    #             #modify initDebt
    #             custName = self.GetItem(item, self.COL_CUSTNAME).GetText()
    #             msg = u'重设<%s>的期初欠款：' %(custName)
    #             caption = u'修改客户期初欠款'
    #             val = self.GetItem(item, self.COL_AMOUNT).GetText()
                
    #             dlg = wx.TextEntryDialog(self, msg, caption, val)
    #             if (dlg.ShowModal() == wx.ID_OK):
    #                 val = dlg.GetValue()
    #                 custObj = self.getCustObj(item)
    #                 custObj.setValue(CDataCustomer.COL_DEBT, float(val))
    #                 custObj.update()
    #                 self.refreshParent()
                    
    #         else:
    #             print 'Error billType: %s' %billType
                
    #     elif (menuItem.GetText() == self.menuList[self.MENU_CUST]):
    #         #以客户过滤单据
    #         custObj = self.getCustObj(item)
    #         custId = custObj.getValue(CDataCustomer.COL_ID)
    #         self.GetParent().setCustomer(custObj)
    #         self.refreshParent()
    #         #self.refresh({'custId':custId})
    
    #     elif (menuItem.GetText() == self.menuList[self.MENU_PAY]):
    #         #付款
    #         debt = -1
    #         saleId = ''            
    #         billType = self.getBillType(item)
    #         if (billType == self.billType[self.BILL_SALE]):
    #             soId = self.getBillId(item)
    #             soObj = CDataSaleOrder.getFirstInstance({CDataSaleOrder.COL_ID:soId})
    #             unpaid = soObj.getUnpaid()
    #             if (unpaid > 0):
    #                 msg = u'是否为<%s>增加付款单\n'\
    #                         u'选是 - 为该销售单付款\n'\
    #                         u'选否 - 新增付款单' %(soId)
    #                 dlg = wx.MessageDialog(self, msg, u'提示消息', wx.YES_NO|wx.ICON_INFORMATION)
    #                 if(dlg.ShowModal() == wx.ID_YES):
    #                     debt = unpaid
    #                     saleId = soId

    #         custObj = self.getCustObj(item)
    #         dlg = DlgPayment.create(self.GetParent())
    #         dlg.setCustData(custObj, debt, saleId)
    #         if(dlg.ShowModal() == wx.ID_OK):
    #             self.refreshParent()
                
    #     elif (menuItem.GetText() == self.menuList[self.MENU_DEL]):
    #         # delete cur bill
    #         if (self.getBillType(item) != self.billType[self.BILL_VOUCHER]):
    #             msg = u'目前只能删除付款单'
    #             dlg = wx.MessageDialog(self, msg, u'提示消息', wx.OK|wx.ICON_INFORMATION)
    #             dlg.ShowModal()
            
    #         msg = u'删除后将无法恢复,确认删除?'
    #         dlg = wx.MessageDialog(self, msg, u'提示消息', wx.YES_NO|wx.ICON_INFORMATION)
    #         if(dlg.ShowModal() == wx.ID_YES):
    #             voucherId = self.getBillId(item)
    #             voucherObj = self.ClsVoucher.getFirstInstance({self.ClsVoucher.COL_ID:voucherId})
    #             voucherObj.delete()
    #             self.refreshParent()
            
    #     else:
    #         print 'Undifined menu %s' %menuItem.GetText()
            
    def getSelectedVoucher(self):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return None
        
        billType = self.getBillType(item)
        if (billType != self.billType[self.BILL_VOUCHER]):
            return None

        id = self.getBillId(item)
        return self.ClsVoucher.getFirstInstance({self.ClsVoucher.COL_ID:id})
    
                            
    def getMainFrame(self):
        #return self.GetParent().GetParent()
        win = self
        while(win.GetParent()):
            win = win.GetParent()
        return win
    
    def refreshParent(self):
        # 影响显示效率的点
        self.GetParent().refresh()
    
    def refreshRemain(self):
        '''刷新数据后，设置‘迄今余额’'''
        self.SortListItems(self.iDate, 1)
        
        remain = 0.0
        for item in range(self.GetItemCount()):
            billType = self.getBillType(item)
            if (billType == self.billType[self.BILL_SALE]):
                remain += float(self.GetItem(item, self.iYingfu).GetText())
            elif(billType == self.billType[self.BILL_VOUCHER]):
                remain -= float(self.GetItem(item, self.iPaid).GetText())
            else:
                remain += float(self.GetItem(item, self.iAmount).GetText())

            self.SetStringItem(item, self.iRemain, '%.2f'%remain) 
    
    def refresh(self, filter={}):
        super(self.__class__, self).refresh(filter)
        self.refreshRemain()
        
        # 显示到最后一行
        self.EnsureVisible(self.GetItemCount()-1)
                    
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'peerId':xx}
        '''
        filterSql = ''
        sale_date_sql = ''
        voucher_date_sql = ''
        data = []
        
        self.m_total = 0
        self.m_paid = 0
        self.m_discount = 0
        self.m_voucherCnt = 0
        self.m_saleCnt = 0
            
        #saleOrder
        if (filter.has_key('peerId')):
            filterSql = 'peerId=%d' %filter['peerId']
            self.m_peerId = filter['peerId']
        
        if (filter.has_key('all') and filter['all'] == 0):
            #peerObj = self.ClsPeer.getFirstInstance({self.ClsPeer.COL_ID:filter['peerId']})
            peerObj = self.ClsPeer.getData({"id":filter['peerId']})
            if (peerObj.getValue(peerObj.COL_SETTLE_DATE) is not None):
                sale_date_sql += " and billDate > '%s' " %(str(peerObj.getValue(peerObj.COL_SETTLE_DATE)))
                voucher_date_sql += " and check_date >  '%s' " %(str(peerObj.getValue(peerObj.COL_SETTLE_DATE)))

                
        saleOrderListRef = self.ClsOrder.fetch(filterSql+sale_date_sql)
        self.m_saleCnt = len(saleOrderListRef)
        for saleOrder in (saleOrderListRef):
            dataRow = []
            
            custId = saleOrder.getValue(saleOrder.COL_PEERID)
            custObj = self.ClsPeer.getData({"id":custId})#getFirstInstance({self.ClsPeer.COL_ID:custId})
            dataRow.append(custObj.getValue(custObj.COL_NAME))
            
            saleId = saleOrder.getValue(saleOrder.COL_ID)
            dataRow.append(saleId)
            dataRow.append(self.billType[self.BILL_SALE])
            # 新增付款账户
            dataRow.append('')
            #paid = CRelFundCustomer.getPaidAmount(saleId)
            amount = saleOrder.getValue(saleOrder.COL_TOTAL)
            discount = saleOrder.getValue(saleOrder.COL_DISCOUNT)
            #unpaid = total - paid - discount
            dataRow.append(amount)
            self.m_total += amount
            #dataRow.append(paid)
            dataRow.append(discount)
            dataRow.append(amount-discount)
            dataRow.append('')
            dataRow.append('')
            #dataRow.append(unpaid)
            
            self.m_discount += discount
            
            dataRow.append(saleOrder.getValue(saleOrder.COL_BILLDATE))
            dataRow.append(saleOrder.getValue(saleOrder.COL_MEMO))
          
            data.append(dataRow)
            
        #voucher
        if (filter.has_key('peerId')):
            filterSql = 'peerId=%d' %filter['peerId']
                
        vouchers = self.ClsVoucher.fetch(filterSql+voucher_date_sql)
        self.m_voucherCnt = len(vouchers)
        for voucher in vouchers:
            dataRow = []
            custId = voucher.getValue(voucher.COL_PEERID)
            custObj = self.ClsPeer.getData({"id":custId})#getFirstInstance({self.ClsPeer.COL_ID:custId})
            dataRow.append(custObj.getValue(custObj.COL_NAME))
            dataRow.append(voucher.getValue(voucher.COL_ID))
            dataRow.append(self.billType[self.BILL_VOUCHER])
            # 新增付款账户
            dataRow.append(voucher.getAccountName())
            
            dataRow.append('')
            dataRow.append('')
            dataRow.append('')
            money = voucher.getValue(voucher.COL_MONEY)
            self.m_paid += money
            dataRow.append(str(money))
            dataRow.append('')
            
            #dataRow.append(voucher.getValue(voucher.COL_DATE))
            dataRow.append(voucher.getValue(voucher.COL_CHECK_DATE))
            dataRow.append(voucher.getValue(voucher.COL_MEMO))
            
            data.append(dataRow)
        
        #InitDebt
        if (filter.has_key('peerId')):
            filterSql = 'id=%d' %filter['peerId']
        custObjs = self.ClsPeer.fetch(filterSql)
        for cust in custObjs:
            dataRow = []
            dataRow.append(cust.getValue(cust.COL_NAME))
            dataRow.append('')
            dataRow.append(self.billType[self.BILL_INITDEBT])
            # 新增付款账户
            dataRow.append('')
            
            initDebt = cust.getValue(cust.COL_DEBT)
            settle_date = ''
            if (sale_date_sql != ''): # 归结后，不显示期初欠款，按归结显示；所有账目，从起初开始显示
                #and cust.getValue(cust.COL_PRE_ARREARS) is not None 
                #and cust.getValue(cust.COL_SETTLE_DATE) is not None):
                initDebt = cust.getValue(cust.COL_PRE_ARREARS)
                settle_date = cust.getValue(cust.COL_SETTLE_DATE)
            self.m_total += initDebt
            dataRow.append(str(initDebt))
            dataRow.append('')
            dataRow.append('')
            dataRow.append('')
            dataRow.append('')
            dataRow.append(settle_date)
            dataRow.append('')
            
            data.append(dataRow)
                    
        return data
    
    def getBillId(self, item):
        return self.GetItem(item, self.iBillId).GetText()
    
    def getBillType(self, item):
        return self.GetItem(item, self.iBillType).GetText()
    
    def isVoucher(self, item):
        return self.getBillType(item) == self.billType[self.BILL_VOUCHER]
    
    def isOrder(self, item):
        return self.getBillType(item) == self.billType[self.BILL_SALE]
    
    def getPeerObj(self, item):
        #name = self.GetItem(item, self.iPeer).GetText()

        #return self.ClsPeer.getFirstInstance({self.ClsPeer.COL_NAME:name})
        return self.ClsPeer.getData({"id":self.m_peerId})


class MyListCtrlPeerSaleDetails(MySortListCtrl):
    ''' 客户/供应商对账-商品明细 '''

    [Type_Customer, Type_Supplier] = [i for i in range(2)]

    def __init__(self, parent, type=Type_Customer):
        self.billType = [u'销售订单', u'付款单据', u'期初欠款']
        [self.BILL_SALE, self.BILL_VOUCHER, self.BILL_INITDEBT] =\
            [i for i in range(len(self.billType))]
            
        self.type = type
        if(self.type == self.Type_Customer):
            self.ClsPeer = CDataCustomer
            self.ClsOrder = CDataSaleOrder
            self.ClsVoucher = CDataVoucher
            self.peerHeader = u'客户名称'
            
        elif(self.type == self.Type_Supplier):
            self.ClsPeer = CDataSupplier
            self.ClsOrder = CDataPurOrder
            self.ClsVoucher = CDataVoucherSupplier
            self.peerHeader = u'供货商名称'
            
            self.billType[self.BILL_SALE] = u'采购订单'
        
        MySortListCtrl.__init__(self, parent, 
                style=wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.LC_HRULES|wx.LC_VRULES)

    def makeCols(self):
        self.iBillId = self.appendCol((u'单号', wx.LIST_FORMAT_LEFT, 0))
        self.iDate = self.appendCol((u'日期', wx.LIST_FORMAT_LEFT, 100))
        self.iProName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 160))
        self.iProSpec = self.appendCol((u'商品规格', wx.LIST_FORMAT_LEFT, 160))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 50))
        self.iNum = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 60))
        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 60))
        self.iTotal = self.appendCol((u'小计', wx.LIST_FORMAT_RIGHT, 60))
        self.iBalance = self.appendCol((u'期末余额', wx.LIST_FORMAT_RIGHT, 80))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 160))
        self.iType = self.appendCol((u'单据类型', wx.LIST_FORMAT_LEFT, 0)) # 0销售 1付款 期初没设置


    def convert(self, filter={}):

        peerObj = self.ClsPeer.getFirstInstance({self.ClsPeer.COL_ID:filter['peerId']})
        if ((filter.has_key('all') and filter['all'] == 1) or peerObj.getValue(peerObj.COL_SETTLE_DATE) is None):
            # 从建账期初开始对账
            data = list(peerObj.getCheckProDetails(True))
            data_begin = ['','',u'期初建账','','','','',''
                ,peerObj.getValue(peerObj.COL_DEBT),''] # 插入期初余额
        else:
            # 从上期对账开始对账
            data = list(peerObj.getCheckProDetails(False))
            data_begin = ['',str(peerObj.getValue(peerObj.COL_SETTLE_DATE)),u'上期期末','','','','',''
                ,peerObj.getValue(peerObj.COL_PRE_ARREARS),''] # 插入期初余额
        data.insert(0,data_begin)
        return data
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

    def refreshBgColour(self):
        for row in range(self.GetItemCount()):            
            if (float(self.GetItem(row, self.iTotal).GetText() or "0") <= 0):
                self.SetItemBackgroundColour(row, wx.Colour(250, 166, 140)) # 无库存，红色
            else:
                self.resetBgcolour(row)

    def refresh(self, filter={}):
        super(self.__class__, self).refresh(filter)
        #self.refreshRemain()
        
        # 显示到最后一行
        self.EnsureVisible(self.GetItemCount()-1)


class MyListCtrlAccountDetailReport(MySortListCtrl):
    ''' 查看账户收支情况 '''
    
    def makeCols(self):
        self.iAccount = self.appendCol((u'账户', wx.LIST_FORMAT_LEFT, 100))
        self.iDate = self.appendCol((u'日期', wx.LIST_FORMAT_RIGHT, 100))
        self.iIncome = self.appendCol((u'收入', wx.LIST_FORMAT_RIGHT, 80))
        self.iExpense = self.appendCol((u'支出', wx.LIST_FORMAT_RIGHT, 80))
        self.iDetail = self.appendCol((u'明细', wx.LIST_FORMAT_LEFT, 160))
        self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT, 80))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 160))
           
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iIncome, self.iExpense])
        
        #self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):

        return CDataAccount.getDetailFromBill(filter['dateStart']
            ,filter['dateEnd']
            ,filter['accountId'] if filter.has_key('accountId') else None)
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyAccountDetailListCtrl(MySortListCtrl):
    '''显示账户明细信息'''
  
##    def __init__(self, parent):
##        self.cols = [(u'编号', wx.LIST_FORMAT_LEFT, 0), 
##                    (u'账户名称', wx.LIST_FORMAT_LEFT, 100), 
##                    (u'日期', wx.LIST_FORMAT_LEFT, 90), 
##                    (u'收入', wx.LIST_FORMAT_LEFT, -1), 
##                    (u'支出', wx.LIST_FORMAT_LEFT, -1),
##                    (u'会款单号',  wx.LIST_FORMAT_LEFT, 160), 
##                    (u'备注', wx.LIST_FORMAT_LEFT, 300)]
##                    
##        [self.COL_ID, self.COL_ACCOUNT, self.COL_DATE , self.COL_INCOME, self.COL_EXPEND,
##        self.COL_BILLID,self.COL_MEMO] =  [i for i in range(len(self.cols))]
##        
##        MySortListCtrl.__init__(self, parent, 
##                style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_VRULES)
##    
##        #self.initMenu()
##        
##        #self.initStatBar()
    
    def makeCols(self):
        cols = [(u'编号', wx.LIST_FORMAT_LEFT, 0), 
                    (u'账户名称', wx.LIST_FORMAT_LEFT, -1), 
                    (u'日期', wx.LIST_FORMAT_LEFT, 90), 
                    (u'收入', wx.LIST_FORMAT_RIGHT, -1), 
                    (u'支出', wx.LIST_FORMAT_RIGHT, -1),
                    #(u'对方账户',  wx.LIST_FORMAT_LEFT, -1),
                    (u'会款单号',  wx.LIST_FORMAT_LEFT, 150),
                    (u'会款单位',  wx.LIST_FORMAT_LEFT, 100), 
                    (u'用项',  wx.LIST_FORMAT_LEFT, 100), 
                    (u'备注', wx.LIST_FORMAT_LEFT, 150),
                    (u'会计科目', wx.LIST_FORMAT_LEFT, -1),
                    (u'系统备注', wx.LIST_FORMAT_LEFT, 200),
                    (u'创建人', wx.LIST_FORMAT_LEFT, 60),
                    (u'创建时间', wx.LIST_FORMAT_LEFT, 140),
                    (u'导入？', wx.LIST_FORMAT_LEFT, -1)]
                
        [self.COL_ID, self.COL_ACCOUNT, self.COL_DATE , self.COL_INCOME, self.COL_EXPEND,
        self.COL_BILLID,self.COL_PEER,self.COL_USEAGE,self.COL_MEMO,self.COL_SUBJECT,self.COL_SYSMEMO,
        self.COL_STAFF, self.COL_TIME, self.COL_LOADIN] = self.appendColList(cols)
                    
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuFilter(self)
        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'新增收付款单')
        self.Bind(wx.EVT_MENU, self.OnPopupMenuVoucher, item) 
        
        self.menu.AppendSeparator()
        
        # 二级菜单 - 编辑
        editMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'编辑选中项', editMenu)
        
        item = editMenu.Append(-1, u'修改用项')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyUseage, item) 
        
        item = editMenu.Append(-1, u'修改备注')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyMemo, item) 

    
        item = editMenu.Append(-1, u'设置付款科目')
        self.Bind(wx.EVT_MENU, self.OnMenuSubject, item)  
        
        item = editMenu.Append(-1, u'修改金额')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyAmount, item)  
 
        self.menu.AppendSeparator()
        
##        # 二级菜单 - 编辑
##        editMenu = wx.Menu()
##        item = self.menu.AppendMenu(-1, u'编辑付款单', editMenu)
##        
##        item = editMenu.Append(-1, u'不解除该付款单与资金账户关联')
##        self.Bind(wx.EVT_MENU, self.OnMenuEditVoucherAlloct, item)  
##        
##        editMenu.AppendSeparator()
##        
##        item = editMenu.Append(-1, u'解除该付款单与资金账户的关联')
##        self.Bind(wx.EVT_MENU, self.OnMenuEditVoucher, item)  
        # 一般没有需要解除的情况，所以暂时不改 
        item = self.menu.Append(-1, u'编辑付款单')
        self.Bind(wx.EVT_MENU, self.OnMenuEditVoucher, item) 
        
        self.menu.AppendSeparator()
        
        # 二级菜单 - 关联已有付款单
        linkMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'关联已有付款单', linkMenu)
        
        item = linkMenu.Append(-1, u'关联客户付款单')
        self.Bind(wx.EVT_MENU, self.OnMenuLinkCustomer, item)
        self.MENU_CUST = item.GetId()
              
        item = linkMenu.Append(-1, u'关联供应商付款单')
        self.Bind(wx.EVT_MENU, self.OnMenuLinkSupplier, item)
        self.MENU_SUPPLIER = item.GetId()
        
        self.menu.AppendSeparator()
                
        MySortListCtrl.appendCommonMenu(self)
    
    def OnMenuModifyAmount(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        val = self.getMoney(item)
        dlg = wx.TextEntryDialog(self, u'修改金额：', u'修改金额：', str(val))
        if (dlg.ShowModal() == wx.ID_OK):
            #保存修改
            val = dlg.GetValue()
            self.updateMoney(item, float(val))
    
    def OnMenuModifyMemo(self, event):            
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        memo = self.GetItem(item, self.COL_MEMO).GetText()
        dlg = wx.TextEntryDialog(self, u'修改备注：', u'修改备注', memo)
        if (dlg.ShowModal() == wx.ID_OK):
            #保存修改
            memo = dlg.GetValue()
            self.updateMemo(item, memo)
    
    def OnMenuModifyUseage(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        txt = self.GetItem(item, self.COL_USEAGE).GetText()
        dlg = wx.TextEntryDialog(self, u'修改用项：', u'修改用项', txt)
        if (dlg.ShowModal() == wx.ID_OK):
            #保存修改
            txt = dlg.GetValue()
            self.updateUseage(item, txt)
        
            
    def OnMenuEditVoucher(self, event):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        voucherId = self.GetItem(item, self.COL_BILLID).GetText()
        if not voucherId:
            return
        
        if voucherId[0] == 'K':
            p = self.getMainFrame().addPageVoucherEditor(voucherId)
            #p.disableMoneyEditor() # panelVoucher自主选择
        elif voucherId[0] == 'G':
            p = self.getMainFrame().addPagePaymentEditor(voucherId)
            #p.disableMoneyEditor()
        else:
            msg = u'未知单号<%s>' %voucherId
            dlg = wx.MessageDialog(self, msg, u'提示消息', wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal() 
           
        
    def OnMenuSubject(self, event):
        import DlgAccountSubject
        dlg = DlgAccountSubject.create(self)
        if dlg.ShowModal() == wx.ID_OK:
            subjectObj = dlg.getSelObj()
            
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return
            
            obj = self.getObj(item)
            obj.setValue(obj.COL_SUBJECT, subjectObj.getKeyVal())
            
            if obj.update() > 0:
                self.SetStringItem(item, self.COL_SUBJECT, subjectObj.getValue(subjectObj.fi_name))
            else:
                print ('Error:update subject error')
            
    include_statBar = True    
    def resetStatValue(self):
        income = 0.0
        expand = 0.0
        
        for row in range(self.GetItemCount()):
            text = self.GetItem(row, self.COL_INCOME).GetText()
            if not (text == '' or text == '\\' or text == '/'):
                income += float(text)

            text = self.GetItem(row, self.COL_EXPEND).GetText()
            if not (text == '' or text == '\\' or text == '/'):
                expand += float(text)
        
        self.tStatList[self.COL_INCOME].SetLabel(str(income))
        self.tStatList[self.COL_EXPEND].SetLabel(str(expand))
        
        #self.resetStatPos()
        
    def OnPopupMenu(self, event):
        '''商品分类右键弹出菜单处理'''
        print 'OnPopupMenu'
        pos = self.ScreenToClient(event.GetPosition())
        self.PopupMenu(self.menu, pos)

    def OnPopupMenuVoucher(self, event):
        '''新增收付款'''
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        if (self.GetItem(item, self.COL_BILLID).GetText() != ''):
            dlg = wx.MessageDialog(self, u'已经为其添加了收付款单据，请先删除单据!', 
                                    u'提示消息', wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal()
            return
        
        income = self.GetItem(item, self.COL_INCOME).GetText()
        expend = self.GetItem(item, self.COL_EXPEND).GetText()
        if (income != ''):
            p = self.getMainFrame().addPageVoucher()
            #p.setAmount(float(income), self.GetParent().getAccountObj())
            p.setAccountDetail(int(self.GetItem(item, self.COL_ID).GetText()))
        elif (expend != ''):
            p = self.getMainFrame().addPagePayment()
            #p.setAmount(float(expend), self.GetParent().getAccountObj())
            p.setAccountDetail(int(self.GetItem(item, self.COL_ID).GetText()))
        else:
            print 'Error unknown income/expend'
            
    def getMainFrame(self):
        #return self.GetParent().GetParent()
        win = self
        while(win.GetParent()):
            win = win.GetParent()
        return win
    
    def getSelectObj(self):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return None
        
        return CDataAccountDetail.findObj(int(self.GetItem(item, self.COL_ID).GetText()))
    
    def OnMenuLinkCustomer(self, event):
        import PanelFund
        self.linkVoucher(PanelFund.Type_Customer)
    
    def OnMenuLinkSupplier(self, event):
        import PanelFund
        self.linkVoucher(PanelFund.Type_Supplier)
    
    def linkVoucher(self, type_peer):
        import PanelFund
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        detailObj = self.getObj(item)
        if detailObj is None:
            return
            
        if (detailObj.getValue(detailObj.COL_FUNDID) != ''):
            dlg = wx.MessageDialog(self, u'已经关联了付款单，暂时不允许修改，请联系开发人员!', 
                                            u'提示消息', wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal()
            return
                    
        dlg = wx.Dialog(self, -1, u'客户账务往来')
        panel = PanelFund.PanelFund(dlg, type_peer)
        panel.setModeLinkVoucher(detailObj)
        
        dlg.SetClientSize(panel.GetSize())
        dlg.CenterOnScreen()
        
        if (dlg.ShowModal() == wx.ID_OK):
            billId = panel.getLinkVoucherId()
            self.updateBillId(item, billId)
                
        dlg.Destroy()
        
    
    def OnPopupMenuSelected(self, event):
        #import DlgPayment,DlgFundCustomer
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
            
        menuItem = self.menu.FindItemById(event.GetId())
        print menuItem.GetText()
        
        if (menuItem.GetId() == self.MENU_CUST):
            money = self.getMoney(item)
            billId = self.GetItem(item, self.COL_BILLID).GetText()
            if (billId != '' and billId[0] != 'K'):
                pass
            
            dlg = DlgFundCustomer.create(self)
            dlg.setBtnAccount(money)
            if(dlg.ShowModal() == wx.ID_OK):
                billId = dlg.getLinkVoucherId()
                self.updateBillId(item, billId)
            
        elif (menuItem.GetId() == self.MENU_SUPPLIER):
            pass
        
        elif (menuItem.GetId() == self.MENU_MODIFY):
            val = self.getMoney(item)
            dlg = wx.TextEntryDialog(self, u'修改金额：', u'修改金额：', str(val))
            if (dlg.ShowModal() == wx.ID_OK):
                #保存修改
                val = dlg.GetValue()
                self.updateMoney(item, float(val))
                
        elif (menuItem.GetId() == self.MENU_MEMO):
            memo = self.GetItem(item, self.COL_MEMO).GetText()
            dlg = wx.TextEntryDialog(self, u'修改备注：', u'修改备注', memo)
            if (dlg.ShowModal() == wx.ID_OK):
                #保存修改
                memo = dlg.GetValue()
                self.updateMemo(item, memo)
    
    def deleteSelection(self):
        rows = []
        item = -1
        while(True):
            item = self.GetNextItem(item, state = wx.LIST_STATE_SELECTED)
            #print item
            if (item == -1):
                break
                
            obj = self.getObj(item)
            obj.delete()
            rows.append(item)
        
        rows.sort(reverse=True)
        for index in range(len(rows)):
            self.DeleteItem(rows[index])
               
    def getObj(self, item):
        id = int(self.GetItem(item, self.COL_ID).GetText())
        return CDataAccountDetail.getFirstInstance({CDataAccountDetail.COL_ID:id})    
    
    def updateUseage(self, item, useage):
        self.SetStringItem(item, self.COL_USEAGE, useage)
        
        id = int(self.GetItem(item, self.COL_ID).GetText())
        obj = CDataAccountDetail.getFirstInstance({CDataAccountDetail.COL_ID:id})
        obj.setValue(CDataAccountDetail.COL_USEAGE, useage)
        obj.update()
        
    def updateMemo(self, item, memo):
        self.SetStringItem(item, self.COL_MEMO, memo)
        
        id = int(self.GetItem(item, self.COL_ID).GetText())
        print id
        obj = CDataAccountDetail.getFirstInstance({CDataAccountDetail.COL_ID:id})
        obj.setValue(CDataAccountDetail.COL_MEMO, memo)
        obj.update()
                    
    def updateBillId(self, item, billId):
        self.SetStringItem(item, self.COL_BILLID, billId)
        
        id = int(self.GetItem(item, self.COL_ID).GetText())
        obj = CDataAccountDetail.getFirstInstance({CDataAccountDetail.COL_ID:id})
        obj.setValue(CDataAccountDetail.COL_FUNDID, billId)
        obj.update()
    
    def updateMoney(self, item, money):
        if(self.GetItem(item, self.COL_INCOME).GetText() != ''):
            self.SetStringItem(item, self.COL_INCOME, str(money))
        else:
            self.SetStringItem(item, self.COL_EXPEND, str(money))
        
        id = int(self.GetItem(item, self.COL_ID).GetText())
        obj = CDataAccountDetail.getFirstInstance({CDataAccountDetail.COL_ID:id})
        obj.setValue(CDataAccountDetail.COL_MONEY, money)
        obj.update()
                
    def refreshParent(self):
        self.GetParent().refresh()
    
    def getMoney(self, item):
        income = self.GetItem(item, self.COL_INCOME).GetText()
        expend = self.GetItem(item, self.COL_EXPEND).GetText()
        if (income == ''):
            income = 0.0
        else:
            income = float(income)
            
        if(expend == ''):
            expend = 0.0
        else:
            expend = float(expend)
        
        return income - expend
                        
    def convert(self, filter={}):
        '''根据filter获取显示数据，并把数据转换为二维列表数据
            filter - {'accountId':xx}
        '''
        filterSql = ''
        data = []
        
        if (filter.has_key('dateStart')):
            filterSql += "date between '%s' and '%s'" \
                            %(filter['dateStart'], filter['dateEnd'])
                            
        if (filter.has_key('accountId')):
            filterSql += ' and accountId=%d' %filter['accountId']
            
        detailList = CDataAccountDetail.fetch(filterSql)
        for detail in (detailList):
            dataRow = []
            dataRow.append(detail.getValue(CDataAccountDetail.COL_ID))
            
            account = detail.getAccount()
            dataRow.append(account.getValue(account.COL_BRIEFNAME))
            
            dataRow.append(detail.getValue(CDataAccountDetail.COL_DATE))
            
            money = detail.getValue(CDataAccountDetail.COL_MONEY)
            if (money > 0):
                dataRow.append(money)
                dataRow.append('')
            else:
                dataRow.append('')
                dataRow.append(-money)
            
            #dataRow.append(detail.getValue(detail.COL_PEERACCOUNT))
            
            #dataRow.append('')# 余额
            dataRow.append(detail.getValue(CDataAccountDetail.COL_FUNDID))
            
            peerName = ''
            voucherId = detail.getValue(CDataAccountDetail.COL_FUNDID)
            if voucherId:
                if voucherId[0] == 'K':
                    peerName = CDataVoucher.getPeerName(voucherId)
                elif voucherId[0] == 'G':
                    peerName = CDataVoucherSupplier.getPeerName(voucherId)
                else:
                    msg = u'提取单位名称失败，未知单号<%s>' %voucherId
                    dlg = wx.MessageDialog(self, msg, u'提示消息', wx.OK|wx.ICON_INFORMATION)
                    dlg.ShowModal()
            dataRow.append(peerName)
            
            dataRow.append(detail.getValue(CDataAccountDetail.COL_USEAGE))
            dataRow.append(detail.getValue(CDataAccountDetail.COL_MEMO))
            dataRow.append(detail.getSubjectName())
            dataRow.append(detail.getValue(CDataAccountDetail.COL_SYSMEMO))
            dataRow.append(detail.getValue(CDataAccountDetail.COL_TIME))
            dataRow.append(detail.getValue(CDataAccountDetail.COL_LOADIN))
            
            data.append(dataRow)
            
        return data

    def resetBgcolour(self, row):
        if int(self.GetItem(row, self.COL_LOADIN).GetText() or "0") == 1:
            self.SetItemBackgroundColour(row, wx.Colour(164, 242, 189))
        else:
            self.SetItemBackgroundColour(row, wx.LIGHT_GREY)
            
            
class MyListCtrlRoute(MySortListCtrl):    
    def getSelectObj(self):
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        id = int(self.GetItemText(item))
        return CDataDeliveryRoute.getFirstInstance({CDataDeliveryRoute.fi_id:id})
        
    def makeCols(self):
        self.iId = self.appendCol((u'ID', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'路线名称', wx.LIST_FORMAT_LEFT, 120))
        #self.iRegion = self.appendCol((u'行经区域', wx.LIST_FORMAT_LEFT, 200))
        self.iLastDelivery = self.appendCol((u'上次送货', wx.LIST_FORMAT_LEFT, 90))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 300))
        self.iCust = self.appendCol((u'客户', wx.LIST_FORMAT_RIGHT, 40))
        self.iEval = self.appendCol((u'评估销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iSales = self.appendCol((u'我司销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iSOM = self.appendCol((u'份额', wx.LIST_FORMAT_RIGHT, 50))
    
    def convert(self, filter={}):
        '''根据filter获取显示数据，并把数据转换为二维列表数据
            filter - {'':xx, }
        '''
        return CDataDeliveryRoute.queryRouteSom()
        data =[]
        
        for obj in CDataDeliveryRoute.getObjList():
            dataRow = []
            dataRow.append(obj.getValue(obj.fi_id))
            dataRow.append(obj.getValue(obj.fi_name))
            dataRow.append("" if obj.getValue(obj.fi_last_delivery) is None else str(obj.getValue(obj.fi_last_delivery)))
            #dataRow.append(CDataDeliveryRoute.getRegionListStr(obj.getValue(obj.fi_id)))
            dataRow.append(obj.getValue(obj.fi_memo))
            
            data.append(dataRow)
            
        return data
        
    include_menu = True
    def makeMenu(self):
        
        MySortListCtrl.appendCommonMenu(self)
         

class __MyListCtrlRouteDetail(MySortListCtrl):
    '''显示路线的行经区域，按index排序'''
    def makeCols(self):
        self.iId = self.appendCol((u'ID', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'次序', wx.LIST_FORMAT_LEFT, 0))
        self.iRegion = self.appendCol((u'行经区域', wx.LIST_FORMAT_LEFT, 100))
        self.iLastTime = self.appendCol((u'上次送货', wx.LIST_FORMAT_LEFT, 100))
        
        self.m_customer_count = 0
    
    def getRegionId(self, item):
        return int(self.GetItemText(item))
    
    def convert(self, filter={}):
        '''根据filter获取显示数据，并把数据转换为二维列表数据
            filter - {'routeId':xx, }
        '''
        data =[]
        self.m_customer_count = 0
        self.m_active_customer_count = 0
        if (not filter.has_key('routeId')):
            list = CDataCustomerRegion.getRegionList()
            self.SetColumnWidth(self.iId, 50)
            self.SetColumnWidth(self.iName, 0)
        else:
            list = CDataDeliveryRoute.getRegionList(filter['routeId'])
        for regionId,index,count,regionName,last_time,active_cnt in list:
            dataRow = []
            dataRow.append(regionId)
            dataRow.append(index)
            dataRow.append(regionName+"("+str(active_cnt)+"/"+str(count)+")")
            dataRow.append("" if last_time is None else str (last_time))
            self.m_customer_count += count
            self.m_active_customer_count += active_cnt
            data.append(dataRow)
            
        return data

class MyListCtrlRouteDetail(MySortListCtrl):
    '''显示路线的行经区域，按index排序'''

    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            self.setStatSum([self.iEval, self.iActual])
        self.tStatList[self.iRegion].SetLabel(u'共%d条'  %self.GetItemCount())

    def makeCols(self):
        self.iId = self.appendCol((u'ID', wx.LIST_FORMAT_LEFT, 0))
        self.iSeq = self.appendCol((u'次序', wx.LIST_FORMAT_LEFT, 0))
        self.iRegion = self.appendCol((u'行经区域', wx.LIST_FORMAT_LEFT, 100))
        self.iLastTime = self.appendCol((u'上次送货', wx.LIST_FORMAT_LEFT, 100))
        self.iEval = self.appendCol((u'评估销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iActual = self.appendCol((u'实际销量', wx.LIST_FORMAT_RIGHT, -1))
        self.iSom = self.appendCol((u'份额', wx.LIST_FORMAT_RIGHT, 50))
        
        self.m_customer_count = 0
    
    def getRegionId(self, item):
        return int(self.GetItemText(item))
    
    def convert(self, filter={}):
        '''根据filter获取显示数据，并把数据转换为二维列表数据
            filter - {'routeId':xx, }
        '''
        data =[]
        self.m_customer_count = 0
        self.m_active_customer_count = 0
        if (not filter.has_key('routeId')):
            list = CDataCustomerRegion.getRegionSom()
            self.SetColumnWidth(self.iId, 0)
            self.SetColumnWidth(self.iSeq, 0)
        elif (filter['routeId'] == -1): # 所有路线外客户
            list = CDataCustomerRegion.getRegionNoSendSom()
            self.SetColumnWidth(self.iId, 0)
            self.SetColumnWidth(self.iSeq, 0)
        elif (filter['routeId'] == -2): # 所有路线内客户
            list = CDataCustomerRegion.getRegionAllSendSom()
            self.SetColumnWidth(self.iId, 0)
            self.SetColumnWidth(self.iSeq, 0)
        else:
            list = CDataDeliveryRoute.getRegionSom(filter['routeId'])

        for regionId,index,count,regionName,last_time,active_cnt,eval_sale,actual_sale,som in list:
            dataRow = []
            dataRow.append(regionId)
            dataRow.append(index)
            dataRow.append(regionName+"("+str(active_cnt)+"/"+str(count)+")")
            dataRow.append("" if last_time is None else str (last_time))
            self.m_customer_count += count
            self.m_active_customer_count += active_cnt
            dataRow.append(eval_sale)
            dataRow.append(actual_sale)
            dataRow.append(som)
            data.append(dataRow)
            
        return data

class MyListCtrlRegionCustomer(MySortListCtrl):
    '''显示区域内客户'''
    
    def makeCols(self):
        self.iId = self.appendCol((u'客户id', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 150))
        self.iDebt = self.appendCol((u'总欠款', wx.LIST_FORMAT_LEFT, 70))
        self.iDebtUnsend = self.appendCol((u'未送单', wx.LIST_FORMAT_LEFT, 60))
        self.iDebtSend = self.appendCol((u'已送单', wx.LIST_FORMAT_LEFT, 60))
        self.iLastOrder = self.appendCol((u'最近采购', wx.LIST_FORMAT_LEFT, 100))
        self.iPhone = self.appendCol((u'联系电话', wx.LIST_FORMAT_LEFT, 110))
        self.iLvlSales = self.appendCol((u'级别', wx.LIST_FORMAT_LEFT, 25))
        self.iWechat = self.appendCol((u'微信', wx.LIST_FORMAT_LEFT, 0))
        self.iCalled = self.appendCol((u'电话', wx.LIST_FORMAT_LEFT, 0))
        self.iOrder = self.appendCol((u'下单', wx.LIST_FORMAT_LEFT, 0))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 0))
        self.iLog = self.appendCol((u'最近联系', wx.LIST_FORMAT_LEFT, 120))
        
    include_menu = True
    def makeMenu(self):
        
        item = self.menu.Append(-1, u'添加客情')
        self.Bind(wx.EVT_MENU, self.OnMenuAddLog, item)

        item = self.menu.Append(-1, u'新建销售单')
        self.Bind(wx.EVT_MENU, self.OnMenuNewOrder, item)

        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'拷贝客户名称')
        self.Bind(wx.EVT_MENU, self.OnMenuCopyName, item)

        item = self.menu.Append(-1, u'拷贝电话')
        self.Bind(wx.EVT_MENU, self.OnMenuCopyPhone, item)    

        self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'查看图片')
        self.Bind(wx.EVT_MENU, self.OnMenuShowImage, item)

        self.menu.AppendSeparator()

        item = self.menu.Append(-1, u'编辑客户')
        self.Bind(wx.EVT_MENU, self.OnMenuEditCustmor, item) 

        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)        
    
    def OnMenuCopyName(self, event):
        import pyperclip
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if item >= 0:
            pyperclip.copy(self.GetItem(item, self.iName).GetText())
    
    def OnMenuCopyPhone(self, event):
        import pyperclip
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if item >= 0:
            pyperclip.copy(self.GetItem(item, self.iPhone).GetText())
            
    # def OnMenuNewOrder(self, event):
        # item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        # if item == -1:
            # p = kit.getRootWin(self).newSaleOrder()
            # p.setDeliveryPlan(self.GetParent().getPlanId())
        # else:
            # custId = int(self.GetItem(item, self.iId).GetText())
            # custObj = CDataCustomer.getData({'id':custId})#.findObj(custId)
            # p = kit.getRootWin(self).newSaleOrder()
            # p.setSelectPeer(custObj)
            # p.setDeliveryPlan(self.GetParent().getPlanId())
    
    def convert(self, filter={}):
        '''根据filter获取显示数据，并把数据转换为二维列表数据
            filter - {'regionId':xx, }
        '''
        
        if (filter.has_key("regionId")):
            return CDataCustomer.getRegionList(filter['planId'],
                filter['regionId'], 
                filter['only_wujindian'],
                filter['only_alarm_customer'],
                filter['only_send_debt'])
        else:
            return CDataCustomer.getRouteList(filter['planId'],
                filter['routeId'], 
                filter['only_wujindian'],
                filter['only_alarm_customer'],
                filter['only_send_debt'])
        # data =[]
        
        # today = datetime.datetime.today().date()
        
        # list = CDataCustomer.getObjs({CDataCustomer.COL_REGION:filter['regionId']})
        # for obj in list:
            # if (filter['only_wujindian'] and obj.getValue(obj.COL_TYPE) != 4):
                # continue
                
            # dataRow = []
            # dataRow.append(obj.getKeyVal())
            # dataRow.append(obj.getValue(obj.COL_NAME))
            
            # lastOrder = u''
            # lastDate = obj.getValue(obj.COL_LASTORDER)
            # if lastDate:
                # span = today - lastDate
                # lastOrder = u'%s(%d天前)' %(lastDate, span.days)
            # dataRow.append(lastOrder)
            
            # dataRow.append(obj.getValue(obj.COL_LMPHONE))

            # data.append(dataRow)
            
        # return data

    def getPeerId(self, item):
        return int(self.GetItem(item, self.iId).GetText())

    def getCustomerId(self, item):
        return int(self.GetItem(item, self.iId).GetText())
        
    def getCustomerObj(self, item):
        id = self.GetItem(item, self.iId).GetText()

        return CDataCustomer.getData({'id':int(id)})#.findObj(id)
        
    def set_item_text(self, item, state, value=""):
        if state == "b_wechat":
            self.SetStringItem(item, self.iWechat, "" if self.GetItem(item, self.iWechat).GetText() == "O" else "O")
        elif state == "b_phone":
            self.SetStringItem(item, self.iCalled, "" if self.GetItem(item, self.iCalled).GetText() == "O" else "O")
        elif state == "b_order":
            self.SetStringItem(item, self.iOrder, "" if self.GetItem(item, self.iOrder).GetText() == "O" else "O")
        elif state == "memo":
            self.SetStringItem(item, self.iMemo, value)


class MyListCtrlOverdueRegion(MySortListCtrl):
    ''' 超期地区 '''

    def makeCols(self):

        self.iRegionId = self.appendCol((u'区域ID', wx.LIST_FORMAT_LEFT, 0))
        self.iRegionName = self.appendCol((u'区域名称', wx.LIST_FORMAT_LEFT, 100))
        self.iRegionLevel = self.appendCol((u'销量', wx.LIST_FORMAT_LEFT, 70))
        self.iImportance = self.appendCol((u'重要性', wx.LIST_FORMAT_LEFT, 70))
        self.iInterval = self.appendCol((u'间隔', wx.LIST_FORMAT_LEFT, 50))
        self.iLast = self.appendCol((u'上次送货', wx.LIST_FORMAT_LEFT, 200))
        self.iActiveCustomer = self.appendCol((u'活跃客户', wx.LIST_FORMAT_RIGHT, 100))
        self.iTotalCustomer = self.appendCol((u'五金店数', wx.LIST_FORMAT_RIGHT, 100))
        self.iroute = self.appendCol((u'适宜路线', wx.LIST_FORMAT_LEFT, 80))
        self.iDistance = self.appendCol((u'距离', wx.LIST_FORMAT_LEFT, 80))
        self.iDriveTime = self.appendCol((u'用时', wx.LIST_FORMAT_LEFT, 80))
        self.iOccupancy = self.appendCol((u'开发程度', wx.LIST_FORMAT_LEFT, 80))
        self.iSalesman = self.appendCol((u'专员', wx.LIST_FORMAT_LEFT, 80))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 100))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        
        self.tStatList[self.iRegionName].SetLabel(u'共%d条记录'  %self.GetItemCount())

        self.setStatSum([self.iActiveCustomer,self.iTotalCustomer])
    
    include_menu = True
    def makeMenu(self):

        item = self.menu.Append(-1, u'编辑地区信息')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyRegion, item)

        self.menu.AppendSeparator()

        MySortListCtrl.appendCommonMenu(self)   

    def getRegionId(self, item):
        return int(self.GetItemText(item))

    def OnMenuModifyRegion(self, event):
        import DlgCustRegionEditor

        if not PermitManager.accessTest(const.PERMIT_MODIFY_ORDER):
            return

        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = DlgCustRegionEditor.create(self)
        dlg.setEditData(CDataCustomerRegion.findObj(self.getRegionId(item)))
        dlg.ShowModal()

    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'all':,}
        '''
             
        return CDataCustomerRegion.query_overdue(salesman = filter['salesman'] if filter.has_key('salesman') else None,
            show_all = filter['show_all'] if filter.has_key('show_all') else False)

            
class MyListCtrlDeliveryPlan(MySortListCtrl):
    '''显示配送计划一览'''
    
    defSortCol = 0
    defSortAscending = 0
    
    def makeCols(self):
        self.iId = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 150))
        self.iRoute = self.appendCol((u'路线', wx.LIST_FORMAT_LEFT, 120))
        self.iState = self.appendCol((u'订单状态', wx.LIST_FORMAT_LEFT,  -1))
        self.iSendDate = self.appendCol((u'发车时间', wx.LIST_FORMAT_RIGHT,  100)) 
        self.iReturnDate = self.appendCol((u'收车时间', wx.LIST_FORMAT_RIGHT,  0))
        self.iTruck = self.appendCol((u'车辆', wx.LIST_FORMAT_RIGHT,  70))
        self.iDriver = self.appendCol((u'司机', wx.LIST_FORMAT_RIGHT,  70))
        self.iFollower = self.appendCol((u'跟车', wx.LIST_FORMAT_RIGHT, 70))
        self.iMemo = self.appendCol((u'备注信息', wx.LIST_FORMAT_LEFT,  150))
        self.iKM = self.appendCol((u'里程', wx.LIST_FORMAT_LEFT,  50))
        self.iHour = self.appendCol((u'用时', wx.LIST_FORMAT_LEFT,  60))
        self.iFee = self.appendCol((u'费用', wx.LIST_FORMAT_LEFT,  50))
    
    include_menu = True
    def makeMenu(self):
        item = self.menu.Append(-1, u'重新编辑')
        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)  
        
        self.menu.AppendSeparator()
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            item = self.menu.Append(-1, u'删除该单据')
            self.Bind(wx.EVT_MENU, self.OnMenuDel, item)  
            
            self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)

        self.menu.AppendSeparator()

        if (b_boss):
            item = self.menu.Append(-1, u'利润试核算')
            self.Bind(wx.EVT_MENU, self.OnMenuProfitCalc, item) 
            self.menu.AppendSeparator()

            # item = self.menu.Append(-1, u'一键结算')
            # self.Bind(wx.EVT_MENU, self.OnMenuVoucherAll, item) 
        
    def OnMenuDel(self, event):
        if not PermitManager.accessTest(const.PERMIT_DEL_ORDER):
            return
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.MessageDialog(self, u'删除后将无法恢复，是否确认删除?',u'提示',
                                wx.YES_NO|wx.NO_DEFAULT|wx.ICON_QUESTION)
        if(dlg.ShowModal() == wx.ID_NO):
            return
            
        billId = self.getPlanId(item)
        CDataDeliveryPlan.tryDelete(billId)
        #看看是不是会影响效率，订单页面似乎没必要保持显示（会产生同步问题）
        self.reloadData()
        
    def OnMenuEdit(self, event):
        if not PermitManager.accessTest(const.PERMIT_MODIFY_ORDER):
            return

        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        kit.getRootWin(self).addPageDeliveryPlan(self.getPlanId())

    def OnMenuProfitCalc(self, event):
        import FrameProfitDelivery
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = FrameProfitDelivery.create(self)
        dlg.setData(self.getPlanId())
        dlg.Show()

    # def OnMenuVoucherAll(self, event):
    #     CDataSaleOrder

    def getPlanId(self, item=-1):
        if item == -1:
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if item == -1:
                return None
        
        return self.GetItem(item, self.iId).GetText()
    
    def convert(self, filter={}):
        '''根据filter显示数据
        
            filter - {'state':,}
        '''
        sql = '1=1 '
        if filter.has_key('dateStart'):
            sql += " and ((plan_date between '%s 00:00:00' and '%s 23:59:59') or (send_date between '%s 00:00:00' and '%s 23:59:59') or (return_date between '%s 00:00:00' and '%s 23:59:59')) " \
                            %(filter['dateStart'], filter['dateEnd'], filter['dateStart'], filter['dateEnd'], filter['dateStart'], filter['dateEnd'])

        if filter.has_key('state'):
            sql += ' and state=%d ' %(filter['state'])
            #planList = CDataDeliveryPlan.getObjs({CDataDeliveryPlan.fi_state:filter['state']})
        else:
            pass
            #planList = CDataDeliveryPlan.getObjList()

        if filter.has_key('not_state'):
            sql += ' and state!=%d ' %(filter['not_state'])
            
        if filter.has_key('truck'):
            sql += " and truck='%s' " %(filter['truck'])

        if filter.has_key('driver'):
            sql += " and (driver=%d or follower1=%d)" %(filter['driver'], filter['driver'])

        #sql += " order by send_date desc " # fetch 会按id降序排列
        planList =  CDataDeliveryPlan.fetch(sql)  
        
        data = []
        for obj in planList:
            dataRow = []
            dataRow.append(obj.getKeyVal())
            dataRow.append(obj.getRouteName())
            dataRow.append(obj.getStateName())
            dataRow.append(obj.getValue(obj.fi_sendDate))
            dataRow.append(obj.getValue(obj.fi_returnDate))
            dataRow.append(obj.getTruckName())
            dataRow.append(obj.getDriverName())
            dataRow.append(obj.getFollowerName())
            dataRow.append(obj.getValue(obj.fi_memo))
            dataRow.append(str(obj.getValue(obj.fi_km_return) - obj.getValue(obj.fi_km_send)) if (obj.getValue(obj.fi_km_return) is not None and obj.getValue(obj.fi_km_send) is not None) else "")
            t = obj.getValue(obj.fi_returnDate) - obj.getValue(obj.fi_sendDate)
            #print type(t)
            #print dir(t)
            dataRow.append("%dh %dm"%(t.total_seconds()//3600,(t.total_seconds()%3600)//60) if t.total_seconds()>0 else "")
            dataRow.append(obj.getValue(obj.fi_toll_fee) + obj.getValue(obj.fi_meals_fee) + obj.getValue(obj.fi_other_fee))
            data.append(dataRow)
        return data
            
        
class MyListCtrlDeliverySaleOrder(MyOrderListCtrl):
    
    def makeCols(self):
        self.iBillId = self.appendCol((u'订单号', wx.LIST_FORMAT_LEFT, 165))
        self.iDate = self.appendCol((u'订单日期', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerName = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 120))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT,  -1)) 
        self.iPaid = self.appendCol((u'已付', wx.LIST_FORMAT_RIGHT,  60))
        self.iUnpaid = self.appendCol((u'未付', wx.LIST_FORMAT_RIGHT,  60))
        self.iDiscount = self.appendCol((u'优惠', wx.LIST_FORMAT_RIGHT, 60))
        self.iState = self.appendCol((u'状态', wx.LIST_FORMAT_LEFT,  60))
        self.iMemo = self.appendCol((u'备注信息', wx.LIST_FORMAT_LEFT,  -1))
        self.iPrinted = self.appendCol((u'打印', wx.LIST_FORMAT_LEFT,  30))
        self.iWechat = self.appendCol((u'微信', wx.LIST_FORMAT_LEFT,  30))
        self.iDlvyMemo = self.appendCol((u'司机报备', wx.LIST_FORMAT_LEFT,  0))
        self.iHandler = self.appendCol((u'经手人', wx.LIST_FORMAT_LEFT,  60))
        self.iPeerId = self.appendCol((u'客户ID', wx.LIST_FORMAT_LEFT,  0))
        self.iDlvyPlan = self.appendCol((u'直送ID', wx.LIST_FORMAT_LEFT,  0))
        self.iPayWay = self.appendCol((u'支付账户', wx.LIST_FORMAT_LEFT,  60))
        self.iDebt = self.appendCol((u'旧账', wx.LIST_FORMAT_LEFT,  -1))
        self.iDlvy = self.appendCol((u'配送', wx.LIST_FORMAT_LEFT,  -1))
    
    def makeMenu(self):

        item = self.menu.Append(-1, u'直接收款')
        self.Bind(wx.EVT_MENU, self.OnMenuVoucherDlg, item) 
                
        item = self.menu.Append(-1, u'新增付款')
        self.Bind(wx.EVT_MENU, self.OnMenuVoucher, item) 
        
        self.menu.AppendSeparator()
                
        # 二级菜单 - 编辑
        editMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'编辑订单', editMenu)
        
        item = editMenu.Append(-1, u'重新编辑订单')
        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)  
        
        editMenu.AppendSeparator()
        item = editMenu.Append(-1, u'修改订单备注')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyMemo, item) 
        
        item = editMenu.Append(-1, u'修改订单状态')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyState, item) 
        
        item = editMenu.Append(-1, u'修改订单配送')
        self.Bind(wx.EVT_MENU, self.OnMenuModifyDlvy, item) 
        
        self.menu.AppendSeparator()
        
        # 二级菜单 - 打印
        printMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'打印单据', printMenu)
        
        item = printMenu.Append(-1, u'打印单据（含应付总额）')
        self.Bind(wx.EVT_MENU, self.OnMenuPrint, item)  
        
        item = printMenu.Append(-1, u'打印单据（不含应付总额）')
        self.Bind(wx.EVT_MENU, self.OnMenuPrintNoDebt, item)  
        
        item = printMenu.Append(-1, u'打印单据（备注附加对账单）')
        self.Bind(wx.EVT_MENU, self.OnMenuPrintWithFund, item)
        
        self.menu.AppendSeparator()
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            # 二级菜单 - 删除  主要是为了避免误点击
            delMenu = wx.Menu()
            item = self.menu.AppendMenu(-1, u'删除订单', delMenu)
            
            item = delMenu.Append(-1, u'删除订单')
            self.Bind(wx.EVT_MENU, self.OnMenuDel, item)  
                
            self.menu.AppendSeparator()        
        
            item = self.menu.Append(-1, u'利润试核算')
            self.Bind(wx.EVT_MENU, self.OnMenuProfitCalc, item) 
            self.menu.AppendSeparator()
        
        item = self.menu.Append(-1, u'司机报备')
        self.Bind(wx.EVT_MENU, self.OnMenuDlvyReport, item)
        
        item = self.menu.Append(-1, u'添加客情')
        self.Bind(wx.EVT_MENU, self.OnMenuAddLog, item)

        self.appendCommonMenu()
    
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnMenuPrint) # 双击打印

    def reloadItem(self, item):
        billId = self.getBillId(item)
        
        return CDataDeliveryPlan.getOrderList(billId = billId)[0]
        
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'deliveryPlan':,}
        '''
        
        return CDataDeliveryPlan.getOrderList(planId = filter['deliveryPlan'])
        
        data = []    
        #saleOrderListRef = CDataSaleOrder.getObjs({CDataSaleOrder.COL_DELIVERYPLAN:filter['deliveryPlan']})
        #filterSql = ''

        #if (filter.has_key('deliveryPlan')):
            #filterSql += " deliveryPlan='%s' " %filter['deliveryPlan']
        
        # saleOrderListRef = CDataSaleOrder.fetch(filterSql)
        # if (saleOrderListRef is None):
            # return 0
            
        # for saleOrder in saleOrderListRef:
            # dataRow = []
            # dataRow.append(saleOrder.getFieldVal('id'))

            # cust = CDataCustomer.getData({'id':saleOrder.getFieldVal('peerId')})
            # dataRow.append(cust.getFieldVal('name'))

            # paid = CRelFundCustomer.getPaidAmount(saleOrder.getValue(CDataSaleOrder.COL_ID))
            # total = saleOrder.getFieldVal('total')
            # discount = saleOrder.getFieldVal('discount')
            # unpaid = kit.myFloat(total) - kit.myFloat(paid) - kit.myFloat(discount)
            # dataRow.append(total)
            # dataRow.append(paid)
            # dataRow.append(unpaid)
            # dataRow.append(discount)
            
            # dataRow.append(saleOrder.getFieldVal('billDate'))
            # dataRow.append(saleOrder.getValue(saleOrder.COL_STATE))
            # #dataRow.append(saleOrder.getDlvyAddr())
# ##            dlvyId = saleOrder.getFieldVal('dlvyId')
# ##            if (dlvyId is None):
# ##                dataRow.append('')
# ##            else:
# ##                dataRow.append(
# ##                    CDataDelivery.getFirstFieldVal({'id':dlvyId},'name'))#Get from other table
            # dataRow.append(saleOrder.getFieldVal('memo'))
            # #dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_HANDLERID)))
            # #dataRow.append(CDataStaff.getName(saleOrder.getValue(saleOrder.COL_RECOREDERID)))
          
            # dataRow.append(u'√' if saleOrder.isPrinted() else u'×')
            # dataRow.append(saleOrder.getValue(saleOrder.COL_PEERID))
            # dataRow.append(saleOrder.getValue(saleOrder.COL_DELIVERYPLAN))
            
            # data.append(dataRow)
            
        # return data
        
class MyListCtrlDeliveryPlanProDetail(MySortListCtrl):
    '''随车产品清单 - 显示配送计划的产品清单'''
    def makeCols(self):
        self.iProId = self.appendCol((u'商品编号', wx.LIST_FORMAT_LEFT, 0))
        self.iPosition = self.appendCol((u'仓位',  wx.LIST_FORMAT_LEFT, 50))
        self.iCust = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 140))
        self.iProName = self.appendCol((u'商品名称', wx.LIST_FORMAT_LEFT, 160))
        self.iProSpec = self.appendCol((u'商品规格',  wx.LIST_FORMAT_LEFT, 160))
        self.iUnit = self.appendCol((u'单位',  wx.LIST_FORMAT_LEFT, 40))
        self.iNum = self.appendCol((u'数量',  wx.LIST_FORMAT_RIGHT, 60))
        self.iPrice = self.appendCol((u'单价',  wx.LIST_FORMAT_RIGHT, 60))
        self.iTotal = self.appendCol((u'总金额', wx.LIST_FORMAT_RIGHT, 70))
        self.iMemo = self.appendCol((u'备注',  wx.LIST_FORMAT_LEFT, 100))
        self.iProMemo = self.appendCol((u'商品备注',  wx.LIST_FORMAT_LEFT, 100))
        self.iQty = self.appendCol((u'库存',  wx.LIST_FORMAT_LEFT, 0))
        
        
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum,self.iTotal])
                
    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'deliveryPlan':,}
        '''

        return CDataSaleOrder.GetDeliveryProducts(filter['deliveryPlan'])
        # data = []    
        # #saleOrderListRef = CDataSaleOrder.getObjs({CDataSaleOrder.COL_DELIVERYPLAN:filter['deliveryPlan']})
        # sql = 'deliveryPlan="%s"'%(filter['deliveryPlan'])
        # saleOrderListRef = CDataSaleOrder.fetch(sql)
        # for saleOrder in saleOrderListRef:
        #     filterSql = "billId='%s'"  %saleOrder.getKeyVal()
        #     objList = CDataSaleDetail.fetch(filterSql)
        #     if (objList is None):
        #         continue

        #     for saleDetail in objList:
        #         dataRow = []
        #         proId = saleDetail.getFieldVal('proId')
        #         proObj = CDataProduct.getInstance({'id':proId})
        #         dataRow.append(proId)
        #         dataRow.append(saleOrder.getPeerName())
        #         dataRow.append(saleDetail.getFieldVal('proName'))
        #         dataRow.append(proObj.getFieldVal('spec'))#spec
        #         dataRow.append(saleDetail.getFieldVal('unit'))
        #         dataRow.append(saleDetail.getFieldVal('num'))
        #         dataRow.append(saleDetail.getFieldVal('price'))
        #         dataRow.append(saleDetail.getFieldVal('total'))
        #         dataRow.append(proObj.getFieldVal('memo'))#pro memo
        #         dataRow.append(proObj.getFieldVal('onhand1'))

        #         data.append(dataRow)
             
        # return data
            
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendMenuShowProDetail(self)
        MySortListCtrl.appendMenuShowProImage(self)

        self.appendCommonMenu()
        
    def getProId(self, item=-1):
        if item == -1:   
            item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
            if (item == -1):
                return -1
            
        return int(self.GetItem(item, self.iProId).GetText())

    def refreshBgColour(self):
        for index in range(self.GetItemCount()):
            if float(self.GetItem(index, self.iQty).GetText()) < 0:
                self.SetItemBackgroundColour(index, wx.Colour(250, 166, 140)) # 负库存，红色
            else:
                self.resetBgcolour(index)

                
class MyListCtrlCustomerLog(MySortListCtrl):
    ''' 客户情况报表 '''
    def makeCols(self):
        self.iLogId = self.appendCol((u'客情id', wx.LIST_FORMAT_LEFT, 0))
        self.iPeerId = self.appendCol((u'客户ID', wx.LIST_FORMAT_LEFT, 0))
        self.iCust = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 150))
        self.iRegion = self.appendCol((u'地区', wx.LIST_FORMAT_LEFT, 100))
        self.iReporter = self.appendCol((u'汇报人', wx.LIST_FORMAT_LEFT, 100))
        self.iTime = self.appendCol((u'汇报时间',  wx.LIST_FORMAT_LEFT, 150))
        self.iContent = self.appendCol((u'汇报内容',  wx.LIST_FORMAT_LEFT, 400))

    def convert(self, filter={}):
        '''根据filter显示数据
            filter - {'dateStart':,'dateEnd','peerId','peerName'}
        '''
        
        
        return CDataCustomer.get_log_list(filter['dateStart']
            , filter['dateEnd']
            , filter['peerId'] if filter.has_key('peerId') else None)
        
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        item = self.menu.Append(-1, u'查询客户')
        self.Bind(wx.EVT_MENU, self.OnMenuSearch, item) 
        
        self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)

    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
                
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())

    def OnMenuSearch(self, event):
        '''设置客户/供货商到搜索栏，以便进行搜索'''
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return

        peerId = self.getPeerId(item)
        peerObj = CDataCustomer.getData({'id':peerId})#.findObj(peerId)
        self.GetParent().search_by_peer(peerObj)#setSelectObj(peerObj)

    def getPeerId(self, item):
        return int(self.GetItem(item, self.iPeerId).GetText())
        
    
class MyListCtrlSaleDayReport(MySortListCtrl):
    '''日销售统计'''
    
    def makeCols(self):
        self.iDate = self.appendCol((u'单据日期', wx.LIST_FORMAT_LEFT, 110))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByDay(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleDayMall(MySortListCtrl):
    '''商城日销售统计'''
    
    def makeCols(self):
        self.iDate = self.appendCol((u'单据日期', wx.LIST_FORMAT_LEFT, 150))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        self.iACV = self.appendCol((u'客单价', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTonglaichaung, self.iYitianda,self.iTotal])
        
        self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByDay(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)
        
class MyListCtrlSaleCustomerReport(MySortListCtrl):
    '''客户销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        self.iStaff = self.appendCol((u'拓新员工', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByCustomer(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleCustomerMall(MySortListCtrl):
    '''商城客户销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'客户名称', wx.LIST_FORMAT_LEFT, 200))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount,self.iTonglaichaung,self.iYitianda])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByCustomer(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)
        
class MyListCtrlSaleCustomerTypeReport(MySortListCtrl):
    '''客户销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'客户类型', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByCustomerType(filter['dateStart'], filter['dateEnd'])
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)
        
class MyListCtrlSaleCustomerRegionReport(MySortListCtrl):
    '''区域销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'区域', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByCustomerRegion(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlSaleCustomerRegionMall(MySortListCtrl):
    '''商城区域销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'区域', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount,self.iTonglaichaung,self.iYitianda])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByCustomerRegion(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlSaleStaffReport(MySortListCtrl):
    '''销售员销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'销售员', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByStaff(filter['dateStart'], filter['dateEnd'])
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleStaffMall(MySortListCtrl):
    '''商城销售员销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'销售员', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount, self.iTonglaichaung, self.iYitianda])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByStaff(filter['dateStart'], filter['dateEnd'])
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)
        
class MyListCtrlSaleDeliveryReport(MySortListCtrl):
    '''送货销售统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'送货方式', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByDelivery(filter['dateStart'], filter['dateEnd'])
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleProductReport(MySortListCtrl):
    '''产品销售统计'''
    
    def makeCols(self):
        self.iPro = self.appendCol((u'产品', wx.LIST_FORMAT_LEFT, 150))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 100))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iQty = self.appendCol((u'销售总数量', wx.LIST_FORMAT_RIGHT, 100))
        self.iAvgPrice = self.appendCol((u'平均单价', wx.LIST_FORMAT_RIGHT, 100))
        self.iMinPrice = self.appendCol((u'最低单价', wx.LIST_FORMAT_RIGHT, 100))
        self.iMaxPrice = self.appendCol((u'最高单价', wx.LIST_FORMAT_RIGHT, 100))
        self.iOnhand = self.appendCol((u'库存', wx.LIST_FORMAT_RIGHT, 100))
        

    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iQty])
        
        self.tStatList[self.iPro].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByProduct(filter['dateStart'], filter['dateEnd'])
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleProductMall(MySortListCtrl):
    ''' 商城产品销售统计 '''
    
    def makeCols(self):
        self.iPro = self.appendCol((u'产品', wx.LIST_FORMAT_LEFT, 150))
        self.iSpec = self.appendCol((u'规格', wx.LIST_FORMAT_LEFT, 100))
        self.iQty = self.appendCol((u'销售总数量', wx.LIST_FORMAT_RIGHT, 100))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))        
        self.iAvgPrice = self.appendCol((u'平均单价', wx.LIST_FORMAT_RIGHT, 100))
        self.iMinPrice = self.appendCol((u'最低单价', wx.LIST_FORMAT_RIGHT, 100))
        self.iMaxPrice = self.appendCol((u'最高单价', wx.LIST_FORMAT_RIGHT, 100))
        self.iOnhand = self.appendCol((u'库存', wx.LIST_FORMAT_RIGHT, 100))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iQty, self.iTonglaichaung, self.iYitianda])
        
        self.tStatList[self.iPro].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByProduct(filter['dateStart'], filter['dateEnd'])
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleCategoryReport(MySortListCtrl):
    '''分类销售统计'''
    
    def makeCols(self):
        self.iName = self.appendCol((u'分类', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iQty = self.appendCol((u'销售总数量', wx.LIST_FORMAT_RIGHT, 100))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iQty])
        
        self.tStatList[self.iName].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByCategory(filter['dateStart'], filter['dateEnd'])
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlSaleCategoryMall(MySortListCtrl):
    '''商城分类销售统计'''
    
    def makeCols(self):
        self.iName = self.appendCol((u'分类', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iQty = self.appendCol((u'销售总数量', wx.LIST_FORMAT_RIGHT, 100))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iQty, self.iTonglaichaung, self.iYitianda])
        
        self.tStatList[self.iName].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByCategory(filter['dateStart'], filter['dateEnd'])
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlSaleMonthReport(MySortListCtrl):
    '''月销售统计'''
    
    def makeCols(self):
        self.iDate = self.appendCol((u'单据日期', wx.LIST_FORMAT_LEFT, 110))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        #self.iPaocheOrders = self.appendCol((u'跑车单数', wx.LIST_FORMAT_RIGHT, 90))
        
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getStatByMonth()
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlSaleMonthMall(MySortListCtrl):
    '''商城月销售统计'''
    
    def makeCols(self):
        self.iDate = self.appendCol((u'单据日期', wx.LIST_FORMAT_LEFT, 110))
        self.iTotal = self.appendCol((u'销售总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iCustomers = self.appendCol((u'客户数', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
        #self.iPaocheOrders = self.appendCol((u'跑车单数', wx.LIST_FORMAT_RIGHT, 90))
        self.iTonglaichaung = self.appendCol((u'同莱创', wx.LIST_FORMAT_RIGHT, 90))
        self.iYitianda = self.appendCol((u'易天达', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount,self.iTonglaichaung,self.iYitianda])
        
        self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getMallStatByMonth()
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)

class MyListCtrlProductMonthReport(MySortListCtrl):
    '''商品月销售统计'''
    
    def makeCols(self):
        self.iMonth = self.appendCol((u'月份', wx.LIST_FORMAT_LEFT, 80))
        self.iNum = self.appendCol((u'销量', wx.LIST_FORMAT_RIGHT, 60))
        self.iAmount = self.appendCol((u'金额', wx.LIST_FORMAT_RIGHT, 80))
           
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum, self.iAmount])
        
        #self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataSaleOrder.getProductStatByMonth(filter['proId'])
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlProductRegionReport(MySortListCtrl):
    '''商品地区一年销售统计'''
    
    def makeCols(self):
        self.iRegion = self.appendCol((u'地区', wx.LIST_FORMAT_LEFT, 80))
        self.iNum = self.appendCol((u'年销量', wx.LIST_FORMAT_RIGHT, 60))
        self.iAmount = self.appendCol((u'年金额', wx.LIST_FORMAT_RIGHT, 80))
           
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iNum, self.iAmount])
        
        #self.tStatList[self.iDate].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        billId = 'XS-' + (datetime.date.today() - datetime.timedelta(days=365)).strftime("%Y-%m-%d") + '-00001'
        return CDataSaleOrder.getProductStatByRegion(filter['proId'], billId)
 
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlSaleSupplierReport(MySortListCtrl):
    '''供货商采购统计'''
    
    def makeCols(self):
        self.iCust = self.appendCol((u'供货商名称', wx.LIST_FORMAT_LEFT, 150))
        self.iTotal = self.appendCol((u'采购总金额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiscount = self.appendCol((u'总优惠', wx.LIST_FORMAT_RIGHT, 90))
        self.iAmount = self.appendCol((u'总应付', wx.LIST_FORMAT_RIGHT, 90))
        self.iOrders = self.appendCol((u'总单数', wx.LIST_FORMAT_RIGHT, 90))
    
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iTotal, self.iDiscount,self.iAmount])
        
        self.tStatList[self.iCust].SetLabel(u'count:%d '%self.GetItemCount())
        
    def convert(self, filter={}):
        return CDataPurOrder.getStat(filter['dateStart'], filter['dateEnd'])

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        MySortListCtrl.appendCommonMenu(self)


class MyListCtrlExpense(MySortListCtrl):
    '''显示费用支出的明细列表
    '''
    
    xlsFile = u'费用支出列表.xlsx'
    def makeCols(self):
        self.iExpenseId = self.appendCol((u'id', wx.LIST_FORMAT_LEFT, 0))
        self.iDate = self.appendCol((u'支出日期', wx.LIST_FORMAT_LEFT, 90))
        self.iAccount = self.appendCol((u'支出账户', wx.LIST_FORMAT_LEFT, 90))
        self.iAmount =  self.appendCol((u'支出金额', wx.LIST_FORMAT_RIGHT, 80))
        self.iSubject = self.appendCol((u'会计科目', wx.LIST_FORMAT_LEFT, 110))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 100))
        self.iCreater = self.appendCol((u'创建人', wx.LIST_FORMAT_LEFT, 100))
        self.iCreateTime = self.appendCol((u'创建时间', wx.LIST_FORMAT_LEFT, 150))        
        self.iUpdater = self.appendCol((u'编辑人', wx.LIST_FORMAT_LEFT, 100))
        self.iUpdateTime = self.appendCol((u'更新时间', wx.LIST_FORMAT_LEFT, 150))
        self.iDeleter = self.appendCol((u'作废人', wx.LIST_FORMAT_LEFT, 100))
        self.iDeleteTime = self.appendCol((u'作废时间', wx.LIST_FORMAT_LEFT, 150))
        self.iDeleteReason = self.appendCol((u'作废原因', wx.LIST_FORMAT_LEFT, 150))
    
    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        
        # 二级菜单 - 编辑
        editMenu = wx.Menu()
        item = self.menu.AppendMenu(-1, u'编辑', editMenu)
        
        item = editMenu.Append(-1, u'编辑')
        self.Bind(wx.EVT_MENU, self.OnMenuEdit, item)        
        
        self.menu.AppendSeparator()
        
        b_boss = conf.getint('permission', 'boss', 0)
        if (b_boss):
            # 二级菜单 - 删除  主要是为了避免误点击
            delMenu = wx.Menu()
            item = self.menu.AppendMenu(-1, u'删除', delMenu)
            
            item = delMenu.Append(-1, u'作废')
            self.Bind(wx.EVT_MENU, self.OnMenuDel, item)  
            
            self.menu.AppendSeparator()
        
        MySortListCtrl.appendCommonMenu(self)
    
    def OnMenuEdit(self, event):
        import DlgExpense
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        obj = CDataExpense.getObj(self.getKeyVal(item))
        
        dlg = DlgExpense.DlgExpense(self)
        dlg.setEditData(obj)
        if dlg.ShowModal() == wx.ID_OK:
            self.refresh(self.curFilter)
    
    def getKeyVal(self, item):
        return self.GetItem(item, 0).GetText()
       
    def OnMenuDel(self, event):
        if not PermitManager.accessTest(const.PERMIT_DEL_ORDER):
            return
        
        item = self.GetNextItem(-1, state = wx.LIST_STATE_SELECTED)
        if (item == -1):
            return
        
        dlg = wx.TextEntryDialog(self, u'请输入作废原因（作废之后可以在回收站查看）：',
                                u'提示',u'',wx.OK|wx.CANCEL|wx.CENTRE)
        if dlg.ShowModal() != wx.ID_OK:
            return       
                    
        CDataExpense.delete_item(self.getKeyVal(item), reason = dlg.GetValue())
        
        #看看是不是会影响效率，订单页面似乎没必要保持显示（会产生同步问题）
        self.refresh(self.curFilter)
           
    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iAmount])
        
    def convert(self, filter={}):
            
        return CDataExpense.getExpenseList(filter.get('subject',None),
                                           filter.get('dateStart', None),
                                           filter.get('dateEnd', None),
                                           filter.get('delete', 0),
                                           filter.get('queryDate', 'update_time'),)


class MyListCtrlAccountCheck(MySortListCtrl):
    '''收款账户对账记录'''
    
    def makeCols(self):
        self.iAccountId = self.appendCol((u'账户ID', wx.LIST_FORMAT_LEFT, 0))
        self.iAccountName = self.appendCol((u'账户', wx.LIST_FORMAT_LEFT, 100))
        self.iDate = self.appendCol((u'对账日期', wx.LIST_FORMAT_RIGHT, 90))
        self.iActualBalance = self.appendCol((u'实际余额', wx.LIST_FORMAT_RIGHT, 100))
        self.iShouldBalance = self.appendCol((u'当期余额', wx.LIST_FORMAT_RIGHT, 100))
        self.iDiff = self.appendCol((u'抽离资金', wx.LIST_FORMAT_RIGHT, 100))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 120))
        self.iLastDate = self.appendCol((u'上期时间', wx.LIST_FORMAT_RIGHT, 100))
        self.iLastBalance = self.appendCol((u'上期余额', wx.LIST_FORMAT_RIGHT, 100))
        self.iSale = self.appendCol((u'当期销售收款', wx.LIST_FORMAT_RIGHT, 100))
        self.iPur = self.appendCol((u'当期采购付款', wx.LIST_FORMAT_RIGHT, 100))
        self.iExpense = self.appendCol((u'当期费用付款', wx.LIST_FORMAT_RIGHT, 100))        
        
    def convert(self, filter={}):
        return CDataAccountCheck.getRecords(filter['account_id'] if filter.has_key("account_id") else -1
            ,filter['date'] if filter.has_key("date") else None)

    # 子类通过覆写makeMenu编辑自定义菜单
    include_menu = True
    def makeMenu(self):
        
        MySortListCtrl.appendCommonMenu(self)

    # 子类通过覆写resetStatValue编辑统计栏显示，简单相加调用setStatSum
    include_statBar = True
    def resetStatValue(self):
        '''实现了统计栏的listctrl在刷新时，重设统计数值'''
        self.setStatSum([self.iActualBalance, self.iShouldBalance, self.iDiff])

        self.tStatList[self.iAccountName].SetLabel(u'cnt:%d '%self.GetItemCount())


class MyCategoryTreeCtrl(wx.TreeCtrl):
    '''呈现商品类别信息，商品类别信息属于页面静态信息，基本保持不变，
        可以在初始化时导入数据
        '''
    def __init__(self, parent):
        wx.TreeCtrl.__init__(self, parent=parent, style=wx.TR_DEFAULT_STYLE| wx.TR_EDIT_LABELS) 
        
        self.SetBackgroundColour(wx.Colour(164, 242, 189))
        self.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL,
              wx.NORMAL, False, u'Times New Roman'))     
        
        self.myInit()
    
    def myInit(self):
        
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
        self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)
##        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK,
##              self.OnTreeItemRightClick)
        
        self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndEdit)      
              
        #右键菜单
        self.categoryMenu = wx.Menu()
        categoryMenuList = [u'添加',u'删除',u'重命名']
        for menuItem in categoryMenuList:
            item = self.categoryMenu.Append(-1, menuItem)
            self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
    
        self.myInitData()
        
    def OnPopupMenu(self, event):
        '''商品分类右键弹出菜单处理'''
        
        
##        pt = event.GetPosition();
##        item, flags = self.HitTest(pt)
##        print 'popup %s' %self.GetItemText(item)
##        if item:
##            self.SelectItem(item)
##        else:
##            return
        print 'OnPopupMenu'
        if self.GetSelection().IsOk():
            log(DBG, 'sel %s', self.GetItemText(self.GetSelection()))
            pos = self.ScreenToClient(event.GetPosition())
            self.PopupMenu(self.categoryMenu, pos)
        #会导致再次弹出菜单？？
        #event.Skip()
            
##    def OnTreeItemRightClick(self, event):
##        
##        print u'OnTreeItemRightClick'
##        print self.GetItemText(event.GetItem())
##        self.SelectItem(event.GetItem())
##        event.Skip()
        
    def OnRightDown(self, event):
        #event.Skip()
        print 'OnRightDown'
        pt = event.GetPosition();
        item, flags = self.HitTest(pt)
        if item:
            #print 'OnRightDown %s' %self.GetItemText(item)
            self.SelectItem(item)
            
    def OnEndEdit(self, event):
        '''保存名称修改'''
        event.Skip()
        
    def getSelection(self):
        '''返回选中项目对应的对象'''
        #return self.GetItemText(self.GetSelection())
        log(TODO, u'如果允许名称冲突，那么要本地存储id，不能再到CDataCategory取值')
        item = self.GetSelection()
        if (not item.IsOk()):
            return None
        
        name = self.getCategoryName(item)
        return CDataCategory.getFirstInstance({CDataCategory.COL_NAME:name})
##        return CDataCategory.getFirstFieldVal({CDataCategory.COL_NAME:name},
##                                               CDataCategory.COL_ID)
    def getCategoryName(self, item):
        return self.GetItemText(item).split('-')[1]

    def setSelection(self, obj):
        '''设置显示产品已关联的对象'''
        if (obj is None):
            return
        
        text = obj.getFieldVal(index=CDataCategory.COL_NAME)
        
        root = self.GetRootItem()
        if (not root.IsOk()):
            return
        
        item = self.search(root, text)
        if (item.IsOk()):
            self.SelectItem(item)
            return
        
        log(LOG_ERR, 'Canot find %s', text)
       
    def search(self,item, text):
        '''递归搜索'''
        log(LOG_DBG, 'comparing %s', self.GetItemText(item))
        
        if self.getCategoryName(item) == text:
            return item
        
        item,cookie = self.GetFirstChild(item)
        while(item.IsOk()):
            ret = self.search(item, text)
            if (ret.IsOk()):
                return ret
            
            item,cookie = self.GetNextChild(item, cookie)
        
        return item
    
    def OnPopupMenuSelected(self, event):
        item = self.categoryMenu.FindItemById(event.GetId())
        treeId = self.GetSelection()
        self.Expand(treeId)
        
        print item.GetText()
        if (item.GetText() == u'添加'):      
            parent = self.getCategoryName(treeId)
            parentId = CDataCategory.getFirstFieldVal({CDataCategory.COL_NAME:parent},
                                                CDataCategory.COL_ID, True)
                    
            msg = u'为<%s>添加新的子类别：' %(parent)
            dlg = wx.TextEntryDialog(self.GetParent(), msg, u'新建商品类别','')
            if dlg.ShowModal() == wx.ID_OK:
                name = dlg.GetValue()
                newCategory = CDataCategory.factory()
                #newCategory.m_fieldVals[product.CDataCategory.getFieldNo(u'name')] = name
                #newCategory.m_fieldVals[product.CDataCategory.getFieldNo(u'parent')] = parent
                newCategory.setMulFieldVal({CDataCategory.COL_NAME:name, 
                                            CDataCategory.COL_PARENT:parentId})
                newCategory.insert()
                newTreeId = self.AppendItem(treeId, name)
                #product.CDataCategory.refreshDataList()
                #self.refreshViewCategory()
                self.SelectItem(newTreeId)
                #self.treeType.Expand(self.treeType.GetSelection())                
        elif (item.GetText() == u'删除'):
            #删除该类别及所有子类
            msg = u'是否删除类别<%s>及其所有子类别' %self.GetItemText(treeId)
            dlg = wx.MessageDialog(self, msg, u'删除商品类别', wx.YES_NO|wx.ICON_QUESTION)
            if dlg.ShowModal() == wx.ID_YES:
                pass
            
        elif(item.GetText() == u'重命名'):
            self.EditLabel(treeId)
            
        else:
            print u'Error'
            return -1
            
    def myInitData(self):
        ready = []
        pend = []
        #self.DeleteAllItems()
        
        for obj in CDataCategory.getObjList():
            parent = obj.getFieldVal(index = CDataCategory.COL_PARENT)
            name = str(obj.getFieldVal(index = CDataCategory.COL_ID))+"-"+obj.getFieldVal(index = CDataCategory.COL_NAME)
            id = obj.getFieldVal(index = CDataCategory.COL_ID)
            
            #find the root and pend the other data.
            log(LOG_INF, u'Category:root %s-%s', (name, parent))
            if (parent is None):
                rootId = self.AddRoot(name)
                ready.append([rootId, id])
                log(LOG_INF, u'Category:root %s', name)
            else:
                #put into unhandled list for later
                pend.append([name, parent, id])
                
        for readyData in ready:
            for pendData in pend:
                if (readyData[1] == pendData[1]):
                    treeId = self.AppendItem(readyData[0], pendData[0])
                    ready.append([treeId, pendData[2]])
                    #iterator BUG? It will make the next item jumped. 
                    #pend.remove(pendData) 
                             
        if len(ready) != len(CDataCategory.getObjList()):
            log(LOG_ERR, u'Category')
            
        self.Expand(rootId)
    
class MyKeywordListCtrl(wx.ListCtrl):
    '''呈现商品关键字信息，商品关键字信息属于页面静态信息，基本保持不变，
        可以在初始化时导入数据
        '''
    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, style=wx.LC_LIST|wx.LC_HRULES|wx.LC_VRULES)
        self.SetBackgroundColour(wx.Colour(164, 242, 189))
        self.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL,
              wx.NORMAL, False, u'Times New Roman'))
              
        self.myInitData()
        
        self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)
        self.menu = wx.Menu()
        self.menuList = [u'添加',u'删除',u'重命名']
        for menuItem in self.menuList:
            item = self.menu.Append(-1, menuItem)
            self.Bind(wx.EVT_MENU, self.OnPopupMenuSelected, item)
            
    def myInitData(self):
        item = 0    
        for obj in CDataKeyword.getObjList():           
            self.InsertStringItem(item, obj.getFieldVal(index = CDataKeyword.COL_NAME))
            item += 1
            
    def OnPopupMenu(self, event):
        '''右键弹出菜单'''
        pos = self.ScreenToClient(event.GetPosition())
        self.PopupMenu(self.menu, pos)
        
    def OnPopupMenuSelected(self, event):
        '''右键菜单选中处理'''
        item = self.menu.FindItemById(event.GetId())     
        print item.GetText()
        
        if (item.GetText() == self.menuList[0]): #添加商品
            dlg = wx.TextEntryDialog(self, u'输入新的商品关键字：', u'新建商品关键字','')
            if dlg.ShowModal() == wx.ID_OK:    
                name = dlg.GetValue().strip()
                if name == '':
                    return
                CDataKeyword.add(name)
                self.InsertStringItem(sys.maxint, name)

import wx.grid
                
class MyGridProductInventory(wx.grid.Grid):
##    def __init__(self, *args, **kw):
##        grid.Grid.__init__(self, *args, **kw)
##        
##        self.myInit()
##        
    def doMyInit(self, proObj=None):
        self._doInitGrid()
        if proObj:
            self.attachProduct(proObj)
        
    def _doInitGrid(self):
        titles = [(u'单位', -1),
                    (u'比例', -1),
                    (u'当前库存数量', -1), 
                    (u'库存变动', -1), 
                    (u'剩余库存', -1)]
        [self.I_UNIT, self.I_RATIO, self.I_STOCK, self.I_CHANGE, 
        self.I_REMAIN] = [i for i in range(len(titles))]
        


        self.ROWS = CDataProduct.UNIT_CNT
        self.CreateGrid(self.ROWS, len(titles))
        for i in range(len(titles)):
            self.SetColLabelValue(i, titles[i][0])
            self.SetColSize(i, titles[i][1])
        self.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
        
        self.SetColLabelSize(32)
        self.SetRowLabelSize(20)
        
        self.SetClientSize(self.GetBestSize())
        
        attr = wx.grid.GridCellAttr()
        attr.SetReadOnly(True)
        self.SetColAttr(self.I_UNIT, attr)
        self.SetColAttr(self.I_RATIO, attr)
        self.SetColAttr(self.I_STOCK, attr)
        self.SetColAttr(self.I_REMAIN, attr)
        
        attr = wx.grid.GridCellAttr()
        attr.SetEditor(wx.grid.GridCellFloatEditor(precision=2))
        self.SetColAttr(self.I_CHANGE, attr)
        
        self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnGridCellChange)
        
    def attachProduct(self, proObj):
        self.m_pro = proObj
        self.unit_cnt = 0
        for i in range(proObj.UNIT_CNT):
            iUnit = proObj.COL_UNIT1 + i * proObj.UNIT_FIELD_CNT
            if proObj.validUnit(iUnit):
                self.unit_cnt += 1
                iRatio = proObj.COL_RATIO1 + i * proObj.UNIT_FIELD_CNT
                iOnhand = proObj.COL_ONHAND1 + i * proObj.UNIT_FIELD_CNT
                self.SetCellValue(i, self.I_UNIT, proObj.getValue(iUnit))
                if proObj.getValue(iRatio):
                    self.SetCellValue(i, self.I_RATIO, str(proObj.getValue(iRatio)))
                self.SetCellValue(i, self.I_STOCK, str(proObj.getValue(iOnhand)))
    
    def adjustInventory(self, unit, cnt):
        for i in range(self.unit_cnt):
            if unit == self.GetCellValue(i, self.I_UNIT):
                self.SetCellValue(i, self.I_CHANGE, str(cnt))
                self.resetRemain(i)
                break
        
        if self.GetCellValue(i, self.I_RATIO) != '' and self.unit_cnt > 1:
            for row in range(self.unit_cnt):
                if self.GetCellValue(row, self.I_RATIO) != '':
                    num = cnt * float(self.GetCellValue(row, self.I_RATIO)) / float(self.GetCellValue(i, self.I_RATIO))
                    self.SetCellValue(row, self.I_CHANGE, str(num))
                    self.resetRemain(row)
                    
    def getLonelyUnit(self, unit):
        ''' return - 与unit无比例关系的字典{unit:change}'''
        if self.unit_cnt <= 1:
            return {}
        
        ret = {}        
        units = []
        for i in range(self.unit_cnt):
            if self.GetCellValue(i, self.I_UNIT) != '':
                units.append(self.GetCellValue(i, self.I_UNIT))
                
        unratio_units = self.m_pro.getUnratioUnit(unit)
        for item in unratio_units:
            row = units.index(item)
            if self.GetCellValue(row, self.I_CHANGE) != '':
                ret[item] = float(self.GetCellValue(row, self.I_CHANGE))
        
        print (u'unratio_units', ret)
        return ret
        
    def resetRemain(self, row):
        try:
            remain = float(self.GetCellValue(row, self.I_STOCK)) + \
                        float(self.GetCellValue(row, self.I_CHANGE))
            self.SetCellValue(row, self.I_REMAIN, str(remain))
        except ValueError as exp:
            kit.showExcept(exp, u'输入错误：请输入数值')
    
    def OnGridCellChange(self, event):
        row = event.GetRow()
        
        if self.GetCellValue(row, self.I_UNIT) == '':
            self.SetCellValue(row, self.I_REMAIN, '')
            self.SetCellValue(row, self.I_CHANGE, '')
            return
            
        self.resetRemain(row)
        

class MyListCtrlOrderSelection(MySortListCtrl):

    def makeCols(self): 
        self.iId = self.appendCol((u'编号', wx.LIST_FORMAT_LEFT, 0))
        self.iName = self.appendCol((u'打印名称', wx.LIST_FORMAT_LEFT, 150))
        self.iUnit = self.appendCol((u'单位', wx.LIST_FORMAT_LEFT, 40))
        self.iNum = self.appendCol((u'数量', wx.LIST_FORMAT_RIGHT, 60))
        self.iPrice = self.appendCol((u'单价', wx.LIST_FORMAT_RIGHT, 60))
        self.iTotal = self.appendCol((u'金额', wx.LIST_FORMAT_RIGHT, 70))
        self.iMemo = self.appendCol((u'备注', wx.LIST_FORMAT_LEFT, 100))
        self.iCharge = self.appendCol((u'运费', wx.LIST_FORMAT_RIGHT, 60))
